ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
3 декабря
837819 Топик полностью
Связанные сообщения
Asn.1
В общем случае, если задача решается в лоб использованием SQL-базы данных, то её и нужно использовать. Будет проще во многом. Др...2020-07-10
Вопрос в том, что первично. Если бинарные данные в текстовом файле (т.е. другие программы будут его осознанно использовать как т...2019-12-05
Истина в том, что не надо всякое дерьмище на уши развешивать и тут же в него уверовать как в абсолютную и единственную истину. Д...2019-01-17
[ASN.1] -> --> Сводный системный топик. Все стандарты (актуальные версии) внутри.2018-06-13
Битовые поля вообще за пределами одной архитектуры с одним компилятором использовать нельзя. Профессиональные решения -- опять ...2018-05-06
На компрессию ссылка не по теме. По сути ASN.1 это такая форма "бинарного XML". Когда данные передаются не неким блобом с неизве...2018-05-05
fk0, легенда (04.05.2018 22:41 - 22:43, просмотров: 898) ответил LightElf на Как обеспечить версионность структур и двустороннюю совместимость при изменениях?
Не понял вопроса. Отвечаю. В 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 и не скажу, какое именно в данном случае возможно решение, особенно применительно к декодеру на вебсайте. Очевидно, что оно в общем случае есть -- для декодера нет проблем воспринять только нужную информацию и откинуть ненужную. Допускаю, в разных средствах это делается по-разному.
[ZX]