文章目录
编码结构
下面说明的均为
primitive
类型,constructed
类型不做讨论。
BER
– Basic encoding rules 基础编码规则
组成部分:
- 标识符(Identifier)
- 长度(Length)
- 内容(Contents)
编码结构如下图所示:
标识符 Identifier
标识符就是表示这个数据结构的类型。
标识符占用 1 字节(byte)
标识符结构如下:
标识符字节各位(bit)详解:
- 第8 - 7位表示这个标签的类别。类别如
Table 1
所示,一般情况下使用Universal
类型,就是00
。 - 第6位
0
表示primitive
标签类型:基本数据类型(不可拆分)1
表示constructed
标签类型:复合数据类型(可拆分)
- 第5 - 1位表示为一个无符号数字,这个数字为这个标签的类型数字。这个数字的最高有效为第5位。
此处所描述的结构只适用于类型小于30种的定义,如果类型超过30就需要使用
high tag number
方式的数据结构,此处不做描述。
长度 Length
长度就是表示Contents
字节数量。
长度的结构有两种构成方式,按照Content
实际的长度(字节数量)来划分:
- 短形式,
Contents
长度小于等于 (<=) 127。 - 长形式,
Contents
长度大于 (>) 127。
短形式
Contents
长度小于等于 (<=) 127
长度占用 1 字节(byte)
短形式字节各位(bit)详解:
- 第8位固定值
0
。 - 第7 - 1位表示一个无符号数字,表示
Contents
中字节数量,其中最高有效位为第7位。(该数字可能为0)
示例:
Length = 38 二进制编码为 0010 0110
长形式
Contents
长度大于 127。
长形式的长度由一个或多个子字节构成。
长形式详解:
- 第1子字节
- 第8位固定值
1
。 - 第7 - 1 位表示一个无符号数字,表示长度的子字节的数量,其中最高有效位为第7位。
- 第一个字节不允许出现
1111 1111
的情况。
- 第8位固定值
- 第1子字节之后的字节,表示一个无符号数字,表示
Contents
中字节数量,其中最高有效位为第1子字节之后的第一个字节的第8 位。
示例:
Length = 201 二进制编码为
1000 0001
1100 1001
内容 Contents
Contents表就是这个数据结构所要表示的值。它由0到多个字节构成,内容的值应该按照对应类型进行对应的编码。
基本类型
布尔类型 BOOLEAN
标识符为:0x01
固定长度:1 (字节)
FALSE
- 单字节中所有位为0,0x00
。
TRUE
- 单字节中所有位为1,0xFF
。
示例:
TRUE
的布尔值编码为:
整形 INTEGER
标识符为:0x02
整形类型的Contents
由0到多个字节构成。
如果整形的值(Contents中的内容)编码数量超过一个字节,那么值的第1个字节(byte)和第二个字节的第8位(bit)应该是下面情况:
- 两者都不应全为
1
。 - 两者都不应全为
0
。
整形类型的Contents
中的字节因为所表示数字的二进制 补码 表示。
正数的补码:等于本身。
如: 1 -
0000 0001
的补码为0000 0001
负数的补码:符号位不变,其它位按位取反,最后再加
1
。如: -1 -
1000 0001
的补码为1111 1111
示例
-1 可以表示为:
128 可以表示为:
如果数字的第1bit为1,通常会在编码前补上一个0字节(byte),也就是0x00
,例如:数字128的编码如下:
Integer value | BER encoding |
---|---|
0 | 02 01 00 |
127 | 02 01 7F |
128 | 02 02 00 80 |
256 | 02 02 01 00 |
-128 | 02 01 80 |
-129 | 02 02 FF 7F |
实数 REAL
标识符为:0x09
如果实数为0,那么这个标签不含有Contents
部分。
如果实数非0,那么Contents
的第一个字节编码规则如下:
- bit 8 = 1(第8位),规则为二进制编码参照的 二进制的编码
- bit 8 = 1 并且 bit 7 = 0,规则为十进制类型编码参照 十进制的编码
- bit 8 = 1 并且 bit 7 = 1,规则为特殊实数编码参照 特殊实数编码
枚举类型 ENUMERATED
标识符为: 0x0a
枚举类型的编码与整形(Integer)一致。
感谢 其实我是真性情 指正
二进制的编码
Contents
的第一个字节的bit 8 = 1,如果实数非0:
设:
- 要表示的数字编码(尾码)为
M
- 符号位为
S
- 正整数数值
N
- 二进制系数
F
(位数)
M
的计算方式如下:
有时需要调整系数
F
以便使得尾码达到编码对齐规则。
Contents
第一个字节编码规则:
- bit 8 固定值
1
- bit 7
- 当
S
为-1时为1
- 当
S
为+1时为0
- 当
- bit 6 - 5 代表基于什么进制,如 Table 2 所示。
- bit 4 - 3 表示二进制系数
F
- bit 2 - 1 指定指数编码的规则:
00
表示Contents
的第2个字节为指数的补码。01
表示Contents
的第2、3字节为指数的补码。10
表示Contents
的第2、3、4字节为指数的补码。11
表示Contents
的第2字节为编码(指数的补码)的长度(字节数),它是一个无符号的二进制数字,设编码长度为X
。那么从第3 到X + 3
字节为指数的补码。X
的值至少为1,指数的前9位不能全为0
或1
。
除去上述描述的字节之后,Contents
剩余的所有字节用于表示整数N
的无符号二进制编码。
十进制的编码
当Contents
的第一个字节的bit 8 to 7 为00
,Contents
中除第一个字节之外的所有内容构成一个Field
。
该Field
在 《ISO 6093》 有具体描述,包括长度和编码。
当Contents
的第一个字节的bit 6 到 1位有以下可选值:
特殊实数编码
当Contents
的第一个字节的bit 8 to 7 为01
,那么Contents
仅有一个字节,它的值可以使下表
比特串 BIT STRING
标识符为:0x03
比特串的Contents
包含一个初始(Initial)字节,它的后面接上0到多个字节。
比特串所表示的值,按照比特串的顺序,从头到尾,每个8bit作为一个字节,依次排列,最后一组不足8位,就补0以达到一个字节。
示例
Contents
中的初始字节,是一个无符号的二进制编码的数,最低有效位为第1位。用来表示最后一个字节中补0的数量。初始化字节的范围为:[0, 7]。
如果 字节串为空,那么不应该有任何子字节,初始化字节为0。
结构示例:
比特串 0x0A3B5F291CD
的二进制编码为:
Contents
第一个字节的0x04
表示补充了4个零。
字节串 OCTET STRING
标识符为:0x04
字节串在Contents
中按照字节串的值的原始顺序,使用0或多个字节,来表示字节串的值。
示例:
字节串 0x00B701
二进制编码为:
空值 NULL
标识符为:0x05
空值Contents
不含任何字节,它的长度(Length)为0。
示例
空值NULL的二进制编码可以表示为:
序列 SEQUENCE
标识符为:0x30
序列的Contents
中包含,除了使用OPTIONAL或DEFAULT类型修饰的关键字之外,序列中含有每一个子项的ASN.1的完整编码,并且按照它们原先在序列中的顺序出现。
如果使用OPTIONAL或DEFAULT类型修饰的关键字的值存在,那么在
Contents
中它们应该出现它们的原本的位置上。
示例:
序列定义为:
SEQUENCE {
age INTEGER,
ok BOOLEAN
}
值为:
{
age 18,
ok TRUE
}
对应的二进制编码为:
数组 SEQUENCE-OF
标识符为:0x30
数组中的元素ASN.1类型都是同种类型的。
数组的Contents
中包含0到多个定义好的的ASN.1值的完整编码,并且按照它们原先在序列中的顺序出现。
示例
BOOLEAN类型的数组定义:
SEQUENCE OF BOOLEAN
值为:
{
TRUE, FALSE, TRUE
}
对应的二进制编码为:
集合 SET
标识符为:0x31
集合的Contents
中包含,除了使用OPTIONAL或DEFAULT类型修饰的关键字之外,序列中含有每一个子项的ASN.1的完整编码,并且按照它们原先在序列中的顺序出现。
示例
集合的值为:
{
TRUE,
777,
0x01020304 --bitString
}
对应的二进制编码为:
SET-OF
标识符为:0x31
SET-OF 基本与 “数组 SEQUENCE-OF ” 一致,在此不做描述。
选择 CHOISE
标识符为:无
选择类型中表示的字段中,该字段可能有多重不同的类型来表示。
选择类型的编码应该与所选中的值的编码相同。
示例
定义一个名为parameter 选择为
parameter CHOISE {
integerType INTEGER,
booleanType BOOLEAN
}
parameter 的值为
parameter booleanType TRUE
对应的二进制编码为:
结束
本次介绍的是常用的ASN.1编码的入门。
这没有对所有的ASN.1类型进行解释,上述描述的基本都是ASN.1的基础类型,其他类型基本上都是上述类型的不同Contents
编码规则。
更多细则和定义请参考 《ITU X.680》***、***《ITU X.690》 。
参考文献
[1] ITU .X.680 . Abstract Syntax Notation One (ASN.1): Specification of basic notation [S] . 2015-08
[3] bj-sys . https://www.obj-sys.com/asn1tutorial/node10.html
[4]. ASN.1 语法・一 . mingfer . https://www.mingfer.cn/2019/04/05/ASN1%E6%8A%BD%E8%B1%A1%E8%AF%AD%E6%B3%95/
[5]. ASN.1 语法・二 . mingfer . https://www.mingfer.cn/2019/04/05/ASN1%E6%8A%BD%E8%B1%A1%E8%AF%AD%E6%B3%95/
[6]. X.690 . wikipedia . https://en.wikipedia.org/wiki/X.690
[7]. A Layman’s Guide to a Subset of ASN.1, BER, and DER . Burton S. Kaliski Jr . 1993 . http://luca.ntop.org/Teaching/Appunti/asn1.html