Pull to refresh

ASN.1 и Erlang

Reading time2 min
Views6K
В давние-предавние времёна, когда компьютеры были большими, а инженеры дальновидными, когда дух маркетологов был неведом рыцарям битов и терминалов, в одном царстве-государстве, у Калинового моста, собрались эти бравые мужи и решили придумать способ представления прозвольных структур данных для передачи их по сети, чтобы их прекрасные дамы могли общаться между собою по телефону и не отвлекали их от решения проблем насущных. Так как маркетологов в тех краях было мало, способ получился изящным и потребляющим мало ресурсов на кодирование/декодирование. И нарекли они его ASN.1, или коротко — X.208.

Протокол ASN.1 описывает структуру данных простым и понятным языком. Например, нам надо описать сообщение, которое будет содержать в себе поле версии (целое число), тип сообщения (перечисление) и тело сообщения (бинарные данные). Мы получим такое описание и сохраним его в файлик SP.asn:

SP DEFINITIONS AUTOMATIC TAGS ::=
BEGIN

Message ::= SEQUENCE
{
  version           INTEGER DEFAULT 1,
  type              MsgType,
  body              Body
}

MsgType ::= ENUMERATED
{
  public(0),
  private(1),
  tralala(2)
}

Body ::= OCTET STRING

END


Есть много разных компиляторов для ASN.1, как платных, так и бесплатных, для разных языков программирования, но мы остановимся на одном из них — компилятор из стандартной поставки Erlang/OTP. Выполним примерно такую команду:

$ erlc SP.asn


После компиляции создастся четыре файла:
  • SP.erl — исходный код кодировщика/декодировщика на языке Erlang
  • SP.hrl — заголовочный файл, содержащий рекорды отдельных описываемых структур
  • SP.beam — BEAM-файл, результат компиляции SP.erl
  • SP.asn1db — файл, содержащий внутерннее представление разобранного ASN.1-файла, используется в тех случаях, когда один файл импортирует структуры другого, чтобы не проводить синтаксический разбор и анализ импортируемого файла лишний раз

Теперь можно с чистой совестью запустить интерпретатор Erlang и закодировать сообщение:
[zert@pluto]:Habrahabr $>> erl
Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
1> rr("SP.hrl").
['Message']
2> {ok, Bin} = 'SP':encode('Message', #'Message'{version = 3, type = private, body = "Hello, ASN.1"}).
{ok,[48,20,128,1,3,129,1,1,130,12,72,101,108,108,111,44,32,65,83,78,46,49]}


Мы получили список байтов, который уже можно передавать по сети, сохранять
на диск и делать прочие действия, которые можно делать с байтами.
Обратное к закодированию действие — раскодирование. Делается это не сложнее, чем кодирование:

3> 'SP':decode('Message', Bin).
{ok,#'Message'{version = 3,type = private,
               body = "Hello, ASN.1"}}


Это самые базовые способы использования компилятора ASN.1 из Erlang/OTP, узнать о нём больше поможет чтение документации, например, вот здесь.
Tags:
Hubs:
Total votes 30: ↑29 and ↓1+28
Comments66

Articles