目录

ASN.1 PER 编码规则

目录

ASN.1定义的编码规则也有很多种,这些编码规则都风格迥异。但目前用得最多、影响也最大的是BER ( Basic Encoding Rules )和 PER ( Packed Encoding Rules) 这两种方案。

BER

BER 编码规定:每个传输的数据值,不管是简单类型还是复合类型,都由 TLC 三个字段构成。 其中:T 是标识类型的八位数组(Tag),L是数据字段的长度(Length),以字节为单位。C 即数据字段的内容(Content)。

TLC 结构是可以嵌套的,在C字段中又可以包含其他数据的 TLC 字段。

PER

由于 BER 的编码包含了过多的冗余信息,使得网络传输负荷过大。 ITU-T 在90年代初又制定了 PER 编码。PER编码规则可以分为基本的(Basic)和规范的(Canonical)两类,每一类又可以分为对齐(aligned variant)和不对齐(unaligned variant)两种。其中, unaligned variant 的编码都是按比特来的,各个数据项的编码之间没有填充的比特,因此它比 aligned variant 更为精简。


PER 的使用必须有一个前提,那就是网络通信的收发双方都清楚正在使用的用 ASN.1句法描述的数据结构,当然这只需要收发双方都遵循统一的通信协议即可。


PER 的编码思路与 BER 有着很大的不同。 它的每种数据类型的编码结果都有[P](导言 optional Preamble) ,[L](长度 optional Length),[C](内容 optional Value)三个字段。

Preamble:导言,表示数据类型的ASN.1句法是否含扩展标记。或SEQUENCE/SET中的可选项、缺省项是否参与编码

Length:数据字段的长度(单位:字节/比特)

Contents:数据字段的内容

与 BER 不同的是 PLC 三个字段都是可选的,而且这三个字段可以以比特为单位,不一定都用字节。

同 BER 一样,PER 的编码具体实现也是嵌套进行的


与 BER 编码比较,PER 编码的精简主要来自于以下三方面:

  1. 没有 T 字段:

T 字段在编码中似乎是一个重要部分,但实际上通常是不必要的。 由于网络的通信双方都遵循统一的网络协议,因此它们可以从数据结构中推导出特定元素的类型和标识,就可以在编码中省略类型标识符。

  1. 长度段的编码更加精简

BER 的长度段的编码都是字节,而且 BER 长度的编码不考虑具体条件;然而 PER 的长度字段根 据编码类型的不同,有不同的单位。这些单位可以是比特、字节、元素、字符等。 这也是 PER 利用数据结构已知的优势来减少编码量的又一方式;而且根据具体的条件限制,PER 的长度段还可以大幅度削 减,譬如当数据类型的长度固定时,该数据项的长度甚至可以不编码。 如下表中的 IA5String(SIZE(4)) ::=“BCDA”,由于长度固定为4,PER 编码就只对 BCDA 进行编码,共4字节。 而 BER 则还要包括 T 和 L 字段,共6字节。PER 长度段的编码规则也要复杂得多,这方面的论述在 X.691中占据了相当大的篇幅。

  1. 对数字类型的编码更加精简

在对 Integer 等数字类型( 包括 Integer 和一些类型的长度值编码的情况) 进行编码时,BER 采取的是直接对数值进行编码;而 PER 采取的是对数据的偏移值( offset) 进行编码。所谓偏移值就是实际值 减去下界的值。 如下表的 Integer (123456789…123456792) ::=123456790,offset=1,PER 只需要对1进行编码,编码结果为“01”,占两个比特。 而PER 就要对1234567690进行编码,编码结果为包括 TLC 三个字段共需要6个字节。这样对于那些下界类型很大的整数,可以节省大量字节,且编码本身也非常简洁。

下表是BER 与 PER 的编码长度比较

ASN.1编码类型 BER Definite length PER Aligned variant
Integer (123456789…123456792) ::=123456790 6 octets 2 bits
Integer (123456789…MAX) ::=123456790 6 octets 2 octets
Integer::=123456790 6 octets 5 octets
IA5String (SIZE (4) ^FROM (“ABCD”) ) ::=“BCDA” 6 octets 1 octet
IA5String (FROM (“ABCD”) ) ::=“BCDA” 6 octets 2 octets
IA5String (SIZE (4) ) ::=“BCDA” 6 octets 4 octets
IA5String::=“BCDA” 6 octets 5 octets
SEQUENCE OF BOOLEAN::= {…共64项…} 195 octets 9 octets
SEQUENCE SIZE (64) OF BOOLEAN::= {…共64项…} 195 octets 8 octets
SEQUENCE OF INTEGER (0..65535) ::= {…共64项…} 195 octets 129 octets
SEQUENCE{a INTEGER (0..7) ,
b BOOLEAN,
c INTEGER (0..3) ,
d SEQUENCE{d1 BOOLEAN,
d2 BOOLEAN}}::={ a 5,
b TRUE,
c 1,
d {d1 TRUE,
d2 TRUE}}
19 octets 1 octets

UPER

  • 非对齐编码:按位被打包,它不会用位填充数据值以生成整数个八位字节。数据本质上是一个有序的比特流。
  • 对齐编码:在位上对值进行编码,但如果某些类型的数据结构编码的位不能被八整除,则会添加填充位,直到整数个八位字节对值进行编码,这意味着可能会有一些浪费的填充位。非对齐编码使用最少的位数,但可能会花费一些处理时间。数据本质上是一个有序字节流。

参考文献:

[1] 吕谦,黄本雄.ASN.1及其两种编码方式(BER和PER)的对比研究[J].数据通信,2001(03):18-21.