Я шел через следующий учебникМне нужен пример, чтобы понять неявной Tagging в ASN.1
http://www.obj-sys.com/asn1tutorial/node12.html
Можете ли вы помочь мне понять, неявное тегирование с примером?
Я шел через следующий учебникМне нужен пример, чтобы понять неявной Tagging в ASN.1
http://www.obj-sys.com/asn1tutorial/node12.html
Можете ли вы помочь мне понять, неявное тегирование с примером?
Я нахожу this thread, чтобы быть достаточно ясным, он также содержит (небольшие) примеры, даже жесткие, они довольно «экстремальные» примеры. Более «реалистичные» примеры, использующие теги IMPLICIT, можно найти в this page.
В пометке 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, кажется смешным даже думать о сохранении двух байтов на тег.
Справка: 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
@AVA Если у вас есть вопрос, почему бы вам не задать вопрос? Почему вы ставите свой вопрос в комментарии? Все дело в том, чтобы задавать вопросы, поэтому идите и задайте вопрос. – Mecki
для меня как примеры для начинающих недостаточно ясны –
Я был потерян в примерах – achabahe