- []
- []
**ASN.1** (англ. //Abstract Syntax Notation One//)
В области телекоммуникаций и компьютерных сетей язык для описания абстрактного синтаксиса данных (ASN.1), используемый OSI. Стандарт записи, описывающий структуры данных для представления, кодирования, передачи и декодирования данных. Он обеспечивает набор формальных правил для описания структуры объектов, которые не зависят от конкретной машины. ASN.1 является ISO и ITU-T совместимым стандартом, первоначально был определён в 1984 году в рамках CCITT X.409:1984. Из-за широкого применения ASN.1 в 1988 году перешёл в свой собственный стандарт X.208. Начиная с 1995 года, существенно пересмотренный ASN.1 описывается стандартом X.680.
В России ASN.1 стандартизирован по ГОСТ Р ИСО/МЭК 8824-1-2001 и ГОСТ Р ИСО/МЭК 8825-93
В Ниже приведен список часто используемых стандартов для Windows, которые написаны на языке ASN.1.
- X.400 (обмена электронными сообщениями)
- X.500 (Directory Services)
- X.200 (связи сеть)
- Протокол доступа к каталогам или LDAP
ASN.1 синтаксис представлен в виде нотаций ASN.1:1988,ASN.1:1990, ASN.1:1997, и ASN.1:2002 , и следующими правилами кодирования BER, CER, DER, PER (aligned или unaligned), XER, CXER, и E-XER.
В общем виде такое описание имеет вид:
data type value name | data type identifier ::= data value
или
{data type identifier (data value)}
Пример определения сообщения в нотации ASN.1:
REPORT DEFINITIONS ::= BEGIN
Report ::= SEQUENCE {
author OCTET STRING,
title OCTET STRING,
body OCTET STRING,
biblio Bibliography
}
Bibliography ::= SEQUENCE {
author OCTET STRING,
title OCTET STRING,
publisher OCTET STRING,
year OCTET STRING
}
END
В этом примере «Report» - имя типа сообщения. SEQUENCE означает, что сообщение является последовательностью элементов данных. Первые четыре элемента имеют тип данных OCTET STRING, т.е. каждый является строкой из восьмибитных байтов (применён термин OCTET (октет), а не BYTE (байт), т.к. на некоторых компьютерах байт состоит не из восьми бит). Элемент «biblio» есть другое определение с именем «Bibliography».
Данный ANS.1 файл report.asn после компиляции:
"C:\ans1-acv644\bin\asn1c" "C:/ans1-acv644/my-2/report.asn" -I ..\csharp\vs2008 -O "C:/ans1-acv644/my-2" -ber -asnstd x208 -xsd -html -c# -depends -compat 6.3 -writer -reader -test -noUniqueNames -dirs -list -warnings
//
// This file was generated by the Objective Systems ASN1C Compiler
// (http://www.obj-sys.com). Version: 6.4.4, Date: 05-Oct-2011.
//
using System;
using Com.Objsys.Asn1.Runtime;
namespace REPORT {
public class Report : Asn1Type {
public Asn1OctetString author;
public Asn1OctetString title;
public Asn1OctetString body;
public Bibliography biblio;
static Report ()
{
Asn1Type.SetKey2 (_REPORTValues._rtkey);
}
public Report () : base()
{
Init();
}
/// <summary>
/// This constructor sets all elements to references to the
/// given objects
/// </summary>
public Report (
Asn1OctetString author_,
Asn1OctetString title_,
Asn1OctetString body_,
Bibliography biblio_
)
: base ()
{
author = author_;
title = title_;
body = body_;
biblio = biblio_;
}
/// <summary>
/// This constructor allows primitive data to be passed for all
/// primitive elements. It will create new object wrappers for
/// the primitive data and set other elements to references to
/// the given objects
/// </summary>
public Report (byte[] author_,
byte[] title_,
byte[] body_,
Bibliography biblio_
)
: base ()
{
author = new Asn1OctetString (author_);
title = new Asn1OctetString (title_);
body = new Asn1OctetString (body_);
biblio = biblio_;
}
public void Init () {
author = null;
title = null;
body = null;
biblio = null;
}
public override void Decode
(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
int llen = (explicitTagging) ?
MatchTag (buffer, Asn1Tag.SEQUENCE) : implicitLength;
Init ();
// decode SEQUENCE
Asn1BerDecodeContext _context =
new Asn1BerDecodeContext (buffer, llen);
IntHolder elemLen = new IntHolder();
// decode author
if (_context.MatchElemTag (Asn1Tag.UNIV, Asn1Tag.PRIM, 4, elemLen, false)) {
buffer.Context.EventDispatcher.StartElement("author", -1);
author = new Asn1OctetString();
author.Decode (buffer, true, elemLen.mValue);
buffer.InvokeCharacters(author.ToString());
buffer.Context.EventDispatcher.EndElement("author", -1);
}
else throw new Asn1MissingRequiredException (buffer);
// decode title
if (_context.MatchElemTag (Asn1Tag.UNIV, Asn1Tag.PRIM, 4, elemLen, false)) {
buffer.Context.EventDispatcher.StartElement("title", -1);
title = new Asn1OctetString();
title.Decode (buffer, true, elemLen.mValue);
buffer.InvokeCharacters(title.ToString());
buffer.Context.EventDispatcher.EndElement("title", -1);
}
else throw new Asn1MissingRequiredException (buffer);
// decode body
if (_context.MatchElemTag (Asn1Tag.UNIV, Asn1Tag.PRIM, 4, elemLen, false)) {
buffer.Context.EventDispatcher.StartElement("body", -1);
body = new Asn1OctetString();
body.Decode (buffer, true, elemLen.mValue);
buffer.InvokeCharacters(body.ToString());
buffer.Context.EventDispatcher.EndElement("body", -1);
}
else throw new Asn1MissingRequiredException (buffer);
// decode biblio
if (_context.MatchElemTag (Asn1Tag.UNIV, Asn1Tag.CONS, 16, elemLen, false)) {
buffer.Context.EventDispatcher.StartElement("biblio", -1);
biblio = new Bibliography();
biblio.Decode (buffer, true, elemLen.mValue);
buffer.Context.EventDispatcher.EndElement("biblio", -1);
}
else throw new Asn1MissingRequiredException (buffer);
if (explicitTagging && llen == Asn1Status.INDEFLEN) {
MatchTag (buffer, Asn1Tag.EOC);
}
}
public override int Encode (Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
int _aal = 0, len;
// encode biblio
buffer.Context.EventDispatcher.StartElement("biblio", -1);
len = biblio.Encode (buffer, true);
_aal += len;
buffer.Context.EventDispatcher.EndElement("biblio", -1);
// encode body
buffer.Context.EventDispatcher.StartElement("body", -1);
len = body.Encode (buffer, true);
_aal += len;
buffer.Context.EventDispatcher.EndElement("body", -1);
// encode title
buffer.Context.EventDispatcher.StartElement("title", -1);
len = title.Encode (buffer, true);
_aal += len;
buffer.Context.EventDispatcher.EndElement("title", -1);
// encode author
buffer.Context.EventDispatcher.StartElement("author", -1);
len = author.Encode (buffer, true);
_aal += len;
buffer.Context.EventDispatcher.EndElement("author", -1);
if (explicitTagging) {
_aal += buffer.EncodeTagAndLength (Asn1Tag.SEQUENCE, _aal);
}
return (_aal);
}
}
}
После работы парсера создается каталог с необходимыми для компиляции исходных файлов в Visual Studio. C VS2008 проблем не будет. В VS2010 проект необходимо будет собрать вручную. При построении проекта используется ans1rt.dll, которая поставляется вместе с парсером, все стальное создается в результате компиляции из файлов:
Bibliography.cs Report.cs REPORT.mk _REPORTValues.cs Reader.cs Writer.cs report.ans
Если есть желание получить готовый проект пишите и задавайте вопросы в форуме. Наша цель, сформировать из выше приведенного файла report.ans программу кодирования (Writer.exe) и декодрования (Reader.exe)
C:\ans1-acv644\my-2\REPORT\writer\bin\Debug>writer.exe -v -o report Encoding was successful Hex dump of encoded record: 30 41 04 09 76 40 a9 cf 43 4b 84 37 de 04 03 31 0A..v@..CK.7...1 6f d3 04 09 e8 41 b1 58 05 c5 fd 46 b0 30 24 04 o....A.X...F.0$. 05 24 fc 7f 8a b7 04 09 4a 97 16 dd 9f a2 48 fb .$.⌂....J.....H. 25 04 05 26 58 aa 25 a5 04 09 61 31 52 b9 e3 c0 %..&X.%...a1R... 59 fd 10 Y.. Binary dump: 0000 : 30 41 : C [UNIVERSAL 16] 65 0002 : 04 09 : P [UNIVERSAL 4] 9 0004 : 76 40 a9 cf 43 4b 84 37 de : v@..CK.7. 0013 : 04 03 : P [UNIVERSAL 4] 3 0015 : 31 6f d3 : 1o. 0018 : 04 09 : P [UNIVERSAL 4] 9 0020 : e8 41 b1 58 05 c5 fd 46 b0 : .A.X...F. 0029 : 30 24 : C [UNIVERSAL 16] 36 0031 : 04 05 : P [UNIVERSAL 4] 5 0033 : 24 fc 7f 8a b7 : $.⌂.. 0038 : 04 09 : P [UNIVERSAL 4] 9 0040 : 4a 97 16 dd 9f a2 48 fb 25 : J.....H.% 0049 : 04 05 : P [UNIVERSAL 4] 5 0051 : 26 58 aa 25 a5 : &X.%. 0056 : 04 09 : P [UNIVERSAL 4] 9 0058 : 61 31 52 b9 e3 c0 59 fd 10 : a1R...Y..
В результате создается бинарный файл report
0000000000: 30 41 04 09 76 40 A9 CF │ 43 4B 84 37 DE 04 03 31 0A♦○v@cПCK"7Ю♦♥1 0000000010: 6F D3 04 09 E8 41 B1 58 │ 05 C5 FD 46 B0 30 24 04 oУ♦○иA+X♣ЕэF°0$♦ 0000000020: 05 24 FC 7F 8A B7 04 09 │ 4A 97 16 DD 9F A2 48 FB ♣$ь⌂?•♦○J-■Э?ўHы 0000000030: 25 04 05 26 58 AA 25 A5 │ 04 09 61 31 52 B9 E3 C0 %♦♣&XЄ%?♦○a1R№гА 0000000040: 59 FD 10 │ Yэ►
Это то что будет в итоге формировать PDU пакет. Затем пробуем прочитать этот бинарный файл (декодируем)
C:\ans1-acv644\my-2\REPORT\reader\bin\Debug>reader.exe -v -i report Decode was successful value = REPORT.Report


