ASN.1 и Erlang

В давние-предавние времёна, когда компьютеры были большими, а инженеры дальновидными, когда дух маркетологов был неведом рыцарям битов и терминалов, в одном царстве-государстве, у Калинового моста, собрались эти бравые мужи и решили придумать способ представления прозвольных структур данных для передачи их по сети, чтобы их прекрасные дамы могли общаться между собою по телефону и не отвлекали их от решения проблем насущных. Так как маркетологов в тех краях было мало, способ получился изящным и потребляющим мало ресурсов на кодирование/декодирование. И нарекли они его 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, узнать о нём больше поможет чтение документации, например, вот здесь.

Оставить комментарий