核心概念
ASN.1是一种形式化表示法,用于描述电信协议传输的数据,无论这些数据的语言实现方式和物理表示形式如何,也无论应用场景复杂与否。
抽象语法标记一号(Abstract Syntax Notation One)是一种标准,它定义了一种用于规范抽象数据类型的形式体系。
该表示法提供了一些预定义的基本类型,例如:整数(INTEGER)、布尔值(BOOLEAN)、字符串(IA5String、通用字符串……)、位串(BIT STRING)、等等,并且可以定义构造类型,例如:结构(SEQUENCE)、列表(SEQUENCE OF)、类型间的选择(CHOICE)、等等。
还可以对任何ASN.1类型应用子类型约束,以限制其值的集合。与许多声称具有可扩展性的其他语法不同,ASN.1提供的可扩展性解决了并支持多年前部署的系统与较新的更新版本之间的互操作性问题。
ASN.1以任何形式(音频、视频、数据等)在需要以数字方式进行通信的任何地方发送信息。ASN.1仅涵盖信息的结构方面(一旦定义了这些值,就没有操作符来处理这些值或进行计算)。因此,它不是一种编程语言。
ASN.1定义可以与ABNF中的“有效语法”概念或XSD中的“有效文档”概念形成对比,在这些概念中,重点完全在于什么是数据的有效编码,而不关心可能附加到此类编码的任何含义。也就是说,没有任何必要的语义联系。
ASN.1成功的主要原因之一是,这种表示法与几种标准化的编码规则相关联,例如BER(基本编码规则),或者最近的PER(压缩编码规则),这些规则对于在带宽方面受到限制的应用程序很有用。
这些编码规则描述了在ASN.1中定义的值应如何编码以便传输(即如何将它们转换为“在线”字节以及反向转换),而与机器、编程语言或它们在应用程序中的表示方式无关。ASN.1的编码比许多竞争表示法更精简,能够快速可靠地传输可扩展消息——这对无线宽带来说是一个优势。
由于ASN.1自1984年以来一直是国际标准,其编码规则已经成熟,并且在可靠性和互操作性方面有着长期良好记录。一个ASN.1定义可以很容易地(通过预运行时处理器)映射到C、C++或Java数据结构,供应用程序代码使用,并且由运行时库提供支持,这些库以XML或TLV格式,或者非常紧凑的压缩编码格式对表示进行编码和解码。
几乎所有操作系统上的工具都支持ASN.1。ASN.1还支持流行的编程语言,如Java、C和C++,以及包括COBOL在内的较旧语言。作为ASN.1通用性的一个例子,有些工具已经被移植到150多个不同的计算平台上。
有许多经过长期使用且经过充分测试的ASN.1工具。使用这些工具,在将新产品推向市场时不太可能出现代价高昂的延迟,更糟糕的是,不太可能因为基于未充分测试缺陷的新代码而召回产品。
ASN.1广泛应用于需要高效(低带宽、低交易成本)计算机通信的行业领域,但也用于需要XML编码数据的领域(例如,生物特征信息的传输)。
case study
假设一家公司拥有多个销售网点,这些网点与一个中央仓库相连,仓库负责库存管理和发货。该公司要求其协议具备以下特点:
- 订单在销售网点本地收集;
- 订单被传输至仓库,由仓库管理发货流程;
- 必须将发货记录反馈给销售网点,以便跟进客户订单。
该协议可以通过以下两个ASN.1模块进行定义:
-- Module sample (sample:01/2014)
Module-order DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Order ::= SEQUENCE {header Order-header,items SEQUENCE OF Order-line
}
Order-header ::= SEQUENCE {number Order-number,date Date,client Client,payment Payment-method
}
Order-number ::= NumericString(SIZE (12))
Date ::= NumericString(SIZE (8)) -- MMDDYYYY
Client ::= SEQUENCE {name PrintableString(SIZE (1..20)),street PrintableString(SIZE (1..50)) OPTIONAL,postcode NumericString(SIZE (5)),town PrintableString(SIZE (1..30)),country PrintableString(SIZE (1..20)) DEFAULT default-country
}default-country PrintableString ::= "France"
Payment-method ::= CHOICE {check NumericString(SIZE (15)),credit-card Credit-card,cash NULL
}
Credit-card ::= SEQUENCE {type Card-type,number NumericString(SIZE (20)),expiry-date NumericString(SIZE (6))-- MMYYYY --
}
Card-type ::= ENUMERATED {cb(0), visa(1), eurocard(2),
diners(3), american-express(4)}
Order-line ::= SEQUENCE {item-code Item-code,label Label,quantity Quantity,price Cents
}
Item-code ::= NumericString(SIZE (7))
Label ::= PrintableString(SIZE (1..30))
Quantity ::= CHOICE {unites INTEGER,millimetres INTEGER,milligrammes INTEGER
}
Cents ::= INTEGER
Delivery-report ::= SEQUENCE {order-code Order-number,delivery SEQUENCE OF Delivery-line
}
Delivery-line ::= SEQUENCE {item Item-code,quantity Quantity
}
END
Protocol DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
IMPORTSOrder, Delivery-report, Item-code, Quantity, Order-number
FROM Module-order;
PDU ::= CHOICE {question CHOICE {question1 Order,question2 Item-code,question3 Order-number,...},answer CHOICE {answer1 Delivery-report,answer2 Quantity,answer3 Delivery-report,...}
}
END