Не понял вопроса. Отвечаю. В ASN.1 и всех нижележащих форматах упаковки (PER/BER/...) подразумевается, что данные несут уже информацию о собственном формате, в каком они записаны. Поля там, конечно, не именованные, но нумерованные тэгами. А уж связь тэга и имени, или там C-структуры, сам как-нибудь обеспечишь. Поэтому чтоб воспринять запись не нужно обладать информацией о её структуре. Её можно просто взять и сразу разобрать, а потом уже думать, это с этим делать. Существуют, например, такие онлайн-декодеры:
https://lapo.it/asn1js или
https://holtstrom. …/tools/asn1decoder.php
Допустим первая версия протокола имела такой вид:
Interface DEFINITIONS ::=
BEGIN
DataPacket ::= [16] SEQUENCE {
seq_num INTEGER,
weight REAL,
name IA5String
}
END
И допустим её скомпилировали и компилятору дали такие данные (в ASN.1 тоже, для примера, но по факту на практике это будет C-структура, например, на входе и BER/PER на выходе):
packet DataPacket ::= {
seq_num 1,
weight 3.5,
name "Simple Packet"
}
На выходе получится такой результат (BER):
B01A3018 02010109 0402332E 35160D53 696D706C 65205061 636B6574
Вставляем его в один из перечисленных выше (см. ссылки) декодеров и получаем такой результат:
[16] {
SEQUENCE {
INTEGER 0x01 (1 decimal)
REAL 02332E35
IA5String 'Simple Packet'
}
}
И видно что пакет имеет тэг [16] и мы знаем со своей стороны что такое [16] (оно есть в изначальном описателе ASN.1 синтаксиса) и следовательно можем восстановить в виде C-структуры, например.
Потом, допустим, прошло время и протокол решили усовершенствовать, для чего добавили дополнительные поля (они помечены ключевым словом OPTIONAL, что подразумевает возможное их отсутствие):
Interface DEFINITIONS ::=
BEGIN
ExtraInfo ::= [17] SEQUENCE {
variable IA5String,
value REAL
}
Timestamp ::= [18] SEQUENCE {
year INTEGER,
mon INTEGER,
day INTEGER
}
DataPacket ::= [16] SEQUENCE {
seq_num INTEGER,
weight REAL,
name IA5String,
price INTEGER OPTIONAL,
date Timestamp OPTIONAL,
extrainfo ExtraInfo OPTIONAL
}
END
Как видно, появились дополнительные поля price, date и extrainfo. Причём каждое из них может либо присутствовать, либо отсутствовать.
Закодируем:
packet DataPacket ::= {
seq_num 1,
weight 3.5,
name "Simple Packet"
-- you may remove following lines --
price 3456,
date {year 2017, mon 01, day 12},
extrainfo {
variable "varname", value 42.0
}
}
И получим в BER:
B040303E 02010109 0402332E 35160D53 696D706C 65205061 636B6574 02020D80
B20C300A 020207E1 02010102 010CB112 30101607 7661726E 616D6509 05023432
2E30
Что декодируется следующим образом:
[16] {
SEQUENCE {
INTEGER 0x01 (1 decimal)
[09] 02332E35
IA5String 'Simple Packet'
INTEGER 0x0D80 (3456 decimal)
[18] {
SEQUENCE {
INTEGER 0x07E1 (2017 decimal)
INTEGER 0x01 (1 decimal)
INTEGER 0x0C (12 decimal)
}
}
[17] {
SEQUENCE {
IA5String 'varname'
[09] 0234322E30
}
}
}
}
Здесь видно, что появились новые структуры [17] и [18] и новое поле INTEGER со значением 3456. Новый декодер способен это понять. Новый декодер так же ожидает возможного отсутствия этих полей и тоже может такое понять. Старый декодер что такое [17] и [18] не знает, хотя знает их структуру. Т.е. может их поэлементно перебрать и распечатать, но он не знает какой смысл имеют эти поля и может их просто откинуть. Аналогично с полем "price" (INTEGER 3456).
На этим сайте
http://asn1-playground.oss.com/ можно потренироваться: вначале вводишь описание синтаксиса и добиваешься его компиляции, потом вводишь описание данных и кодируешь, потом хексы можно скопировать в сторонние декодеры, а можно и тут же декодировать обратно. При декодировании учитывается знание синтаксиса из левого верхнего окна, поэтому, например, последний хекс-пакет с расширенным синтаксисом (последней версией) декодируется так:
tag = [16] constructed; length = 64
DataPacket SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 62
seq_num INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
1
weight REAL: tag = [UNIVERSAL 9] primitive; length = 4
"3.5"
name IA5String: tag = [UNIVERSAL 22] primitive; length = 13
"Simple Packet"
price INTEGER: tag = [UNIVERSAL 2] primitive; length = 2
3456
date : tag = [18] constructed; length = 12
Timestamp SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 10
year INTEGER: tag = [UNIVERSAL 2] primitive; length = 2
2017
mon INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
1
day INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
12
extrainfo : tag = [17] constructed; length = 18
ExtraInfo SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 16
variable IA5String: tag = [UNIVERSAL 22] primitive; length = 7
"varname"
value REAL: tag = [UNIVERSAL 9] primitive; length = 5
"42.0"
Successfully decoded 66 bytes.
rec1value DataPacket ::=
{
seq_num 1,
weight 35E-1,
name "Simple Packet",
price 3456,
date
{
year 2017,
mon 1,
day 12
},
extrainfo
{
variable "varname",
value 420E-1
}
}
А если в левом верхнем окне подсунуть старый упрощённый синтаксис без лишних полей, скомпилировать и потом декодировать, то выйдет следущее:
tag = [16] constructed; length = 64
DataPacket SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 62
seq_num INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
1
weight REAL: tag = [UNIVERSAL 9] primitive; length = 4
"3.5"
name IA5String: tag = [UNIVERSAL 22] primitive; length = 13
"Simple Packet"
D0047E: Tag not recognized: [UNIVERSAL 2]; check PDU #1 'DataPacket'.
*SKIPPED*: tag = [UNIVERSAL 2] primitive; length = 2
<skipped>
D0047E: Tag not recognized: [18]; check PDU #1 'DataPacket'.
*SKIPPED*: tag = [18] constructed; length = 12
<skipped>
D0047E: Tag not recognized: [17]; check PDU #1 'DataPacket'.
*SKIPPED*: tag = [17] constructed; length = 18
<skipped>
S0012E: Decoding of PDU #1 failed with the return code '5'.
Как видишь, не распознало новые поля. Честно говоря, я не большой специалист по ASN.1 и не скажу, какое именно в данном случае возможно решение, особенно применительно к декодеру на вебсайте. Очевидно, что оно в общем случае есть -- для декодера нет проблем воспринять только нужную информацию и откинуть ненужную. Допускаю, в разных средствах это делается по-разному.