2010-07-21 4 views

ответ

2

Я нахожу this thread, чтобы быть достаточно ясным, он также содержит (небольшие) примеры, даже жесткие, они довольно «экстремальные» примеры. Более «реалистичные» примеры, использующие теги IMPLICIT, можно найти в this page.

+1

для меня как примеры для начинающих недостаточно ясны –

+0

Я был потерян в примерах – achabahe

23

В пометке ASN.1, по сути, служит две цели: набрав и называя. Ввод означает, что он сообщает en-/decoder, какой тип данных (это строка, целое число, логическое значение, набор и т. Д.), Именование означает, что если имеется несколько полей одного типа и некоторых (например, или все из них) являются необязательными, он сообщает en-/decoder, для какого поля это значение.

Если сравнивать ASN.1 к, скажем, JSON, и вы посмотрите на следующие данные JSON:

"Image": { 
    "Width": 800, 
    "Height": 600, 
    "Title": "View from 15th Floor" 
} 

Вы заметите, что в формате JSON каждое поле всегда явно назван («Image» , «Ширина», «Высота», «Название») и явно или неявно напечатано («Заголовок» - это строка, потому что ее значение окружено кавычками, «Ширина» является целым числом, поскольку она не содержит кавычек, только цифры , это не «null», «true» или «false», и он не имеет десятичного периода).

В ASN.1 эта часть данных будет:

Image ::= SEQUENCE { 
    Width INTEGER, 
    Height INTEGER, 
    Title UTF8String 
} 

Это будет работать без каких-либо специальных тегов, здесь только универсальные теги необходимы. Universal tags не называют данные, они просто вводят данные, поэтому эн-/декодер знает, что первые два значения являются целыми числами, а последний - строкой. То, что первым целым является Width, а второй - Height, не нужно кодировать в потоке байтов, он определяется их порядком (последовательности имеют фиксированный порядок, наборы нет. На странице, которую вы ссылались на множества, быть использованным).

Теперь изменить схему следующим образом:

Image ::= SEQUENCE { 
    Width INTEGER OPTIONAL, 
    Height INTEGER OPTIONAL, 
    Title UTF8String 
} 

Хорошо, теперь у нас есть проблемы. Предположим, что получены следующие данные:

INTEGER(750), UTF8String("A funny kitten") 

Что такое 750? Ширина или высота? Может быть ширина (и высота отсутствует) или может быть Высота (и ширина отсутствует), оба будут выглядеть так же, как бинарный поток. В JSON, который был бы ясен, поскольку каждый фрагмент данных назван, в ASN.1 это не так. Теперь одного типа недостаточно, теперь нам также нужно имя. Вот где не универсальные теги входят в игру. Измените его на:

Image ::= SEQUENCE { 
    Width [0] INTEGER OPTIONAL, 
    Height [1] INTEGER OPTIONAL, 
    Title UTF8String 
} 

И если вы получаете следующие данные:

[1]INTEGER(750), UTF8String("A funny kitten") 

Вы знаете, что 750 является высота и не Ширина (там просто нет Ширина). Здесь вы объявляете новый тег (в этом случае контекстно-зависимый), который выполняет две цели: он сообщает en-/decoder, что это целочисленное значение (ввод), и оно сообщает, какое целочисленное значение является (именованием).

Но в чем разница между неявной и явной пометкой? Разница заключается в том, что неявное тегирование просто называет данные, en-/decoder необходимо знать тип неявно для этого имени, в то время как явные имена тегов и явно вводит данные.

Если пометка явно, то данные будут посланы как:

[1]INTEGER(xxx), UTF8String(yyy) 

так, даже если декодер не имеет ни малейшего представления о том, что [1] означает, что высота, он знает, что байты «ххх» должны быть разобраны/интерпретируется как целочисленное значение. Другим важным преимуществом явной маркировки является то, что тип может быть изменен в будущем без изменения тега. Например.

Length ::= [0] INTEGER 

может быть изменен на

Length ::= [0] CHOICE { 
    integer INTEGER, 
    real REAL 
} 

Tag [0] по-прежнему означает длину, но теперь длина может быть либо целым числом, или значение с плавающей точкой. Поскольку тип кодируется явно, декодеры всегда будут знать, как правильно декодировать значение, и это изменение, таким образом, совместимо по принципу «вперед» и «назад» (по крайней мере, на уровне декодера, не обязательно обратно совместимым на уровне приложения).

Если пометка подразумевается, что данные будут посланы как:

[1](xxx), UTF8String(yyy) 

декодер, который не знает, что [1], не будет знать тип «ххх» и, таким образом, не может разобрать/правильно интерпретировать эти данные. В отличие от JSON, значения в ASN.1 - это просто байты. Таким образом, «xxx» может быть одним, двумя, тремя или, возможно, четырьмя байтами, и как декодировать эти байты, зависит от их типа данных, который не предоставляется в самом потоке данных. Также изменение типа [1] наверняка нарушит существующие декодеры.

Хорошо, но зачем кому-то использовать неявные теги? Разве не лучше всегда использовать явные тегирования? При явной маркировке тип также должен быть закодирован в потоке данных, и для этого потребуется два дополнительных байта. Для передачи данных, содержащих несколько тысяч (может быть, даже миллионов) тегов и где, возможно, каждый байт подсчитывает (очень медленное соединение, крошечные пакеты, высокая потеря пакетов, очень слабые устройства обработки), и в любом случае обе стороны знают все пользовательские теги, , памяти, времени хранения и/или обработки для кодирования, передачи и декодирования ненужной информации о типе?

Имейте в виду, что ASN.1 является довольно старым стандартом, и он был предназначен для достижения очень компактного представления данных в то время, когда пропускная способность сети была очень дорогостоящей и обрабатывалась в несколько сотен раз медленнее, чем сегодня. Если вы посмотрите на все сегодняшние передачи данных XML и JSON, кажется смешным даже думать о сохранении двух байтов на тег.

+0

Справка: https://osqa-ask.wireshark.org/questions/8277/difference-between-implicit-and-explicit -tags-ASN1. Здесь a) A :: = INTEGER со значением 5 кодируется как hex 02 01 05, b) B :: = [2] IMPLICIT INTEGER со значением 5 кодируется как hex 82 01 05 и c) C :: = [2 ] EXPLICIT INTEGER со значением 5 закодирован как hex A2 03 02 01 05. Может ли кто-нибудь объяснить случай b и регистр c! – AVA

+0

@AVA Если у вас есть вопрос, почему бы вам не задать вопрос? Почему вы ставите свой вопрос в комментарии? Все дело в том, чтобы задавать вопросы, поэтому идите и задайте вопрос. – Mecki