ASN.1 BER Encode Integer 0x10000000FFFFFFFC Кодирование неопределенной длины
Я реализую BER в соответствии со спецификацией и задаю себе вопрос: как бы я кодировал Integer 0x10000000FFFFFFFC как BER Integer (тег 0x02), когда я использую кодирование с неопределенной длиной?
До сих пор я не обнаружил никаких экранирующих символов в спецификации, поэтому предположил бы, что не могу кодировать такое число и поэтому должен был бы полагаться на отправителя, чтобы узнать это, и отправить Integer с короткой кодировкой длины формы. Но в BitStrings возникает та же проблема.
3 ответа
Вы НИКОГДА не используете кодирование неопределенной длины с целым числом...
Это написано в главе 8.3 X.690 (08/2015) (Кодирование целочисленного значения):
The encoding of an integer value shall be primitive
Неопределенная длина используется для созданных типов (SEQUENCE, SEQUENCE OF ...) и для базовых типов, которые могут содержать большие значения (строковые типы, BITSTRING, OCTET STRING ...). В этом случае спецификация скажет:
The encoding of a bitstring value shall be either primitive or constructed at the option of the sender
Правила кодирования CER (глава 9) дают вам представление о том, что означало большое значение во время написания:
Bitstring, octetstring, and restricted character string values shall be encoded with a primitive encoding if they would require no more than 1000 contents octets, and as a constructed encoding otherwise
Итак, вы видите, что даже гигантское целое число всегда будет меньше 1000 байтов при кодировании: отсюда выбор никогда не использовать форму неопределенной длины для целого числа
AFAIK, кодирование с неопределенной длиной определяется только для строк октетов / битов, но не для числовых типов.
Кроме того, я не думаю, что в BER есть какой-либо механизм спасения.
Кодирование неопределенной длины всегда содержит порции данных (строки октетов / битов), закодированные с использованием кодирования определенной длины. На языке BER неопределенная длина всегда находится в построенном виде.
При кодировании определенной длины у вас всегда есть счетчик байтов, чтобы разрезать поток октетов по определенной позиции, вам не нужно никакого дозорного.
При кодировании с неопределенной длиной вам нужны эти два нуля-страж (которые на самом деле являются триплетом TVL со значением нулевой длины) для указания конца данных. Но у вас никогда не будет необработанных, например, некодированных данных (которые в противном случае могли бы повлиять на страж) в качестве полезной нагрузки.
Вы обеспокоены сценарием, в котором (а) используется альтернативное построенное кодирование, показанное на рисунке 2, и (б) октеты содержимого содержат октеты 0x0000, которые (неправильно) будут интерпретироваться как маркер конца содержимого.
Когда я впервые прочитал вопрос, мой первый инстинкт был, конечно, BER сказать что-то об этом. Может быть, есть механизм выхода, чтобы избежать 0x0000 в содержимом. Может быть, правила кодирования таковы, что 0x0000, естественно, никогда не произойдет.
Но после тщательного сканирования спецификации X.690 несколько раз я не мог найти ничего подобного.
Итак, я думаю, что вы правы: я думаю, что отправитель должен не использовать альтернативное построенное кодирование в таких сценариях (что на практике означает, что никогда не следует использовать альтернативное построенное кодирование для типов данных, которые имеют эту потенциальную проблему, например, целые числа и bitstrings).
Для сравнения, Thrift разрешает маркер STOP (байт 00) только в очень специфических обстоятельствах в качестве маркера "больше нет полей" при кодировании структуры (см. https://github.com/erikvanoosten/thrift-missing-specification/blob/master/rpc-spec-binary-protocol.asciidoc)