ASN.1编码规则
ASN.1规则中数据的表示方法以及各数据类型的描述
ASN.1编码规则
ASN.1
BER(BasicEncoding Rules)是 ASN.1 中最早定义的编码规则,其他编码规则是在 BER 的基础上添加新的规则构成。
BER 传输语法是基于八位组大端编码的,高八位在左。
BER 传输语法的格式一直是 TLV 三元组
| Tag | Length | Value |
|---|---|---|
| 类型 | Value 的长度 | 值 |
Tag
Tag 是一个或若干个八位组
目前我遇到的都只有一个八位组,所以一下仅写 universalTag 类型
| 7 | 6 | 5 | 4~0 |
|---|---|---|---|
| 0 | 0 | 0/1 | 0~30 |
7、6 位指明 Tag 的类型,00 表示 UniversalTag 类型;
5 位指明该类型以 primitive 方式编码还是 constructed 方式编码;
因此 SEQUENCE、SET 类型 Tag 对应 16(0x10)、17(0x11)将编码为 0x30、0x31
4~0 位指明对应的 UniversalTag 类型(值是 0-30):注意这里的 30 是十进制。
ASN.1 中定义的 UNIVERSAL 类 Tag
| Tag | 16 进制编码 | 类型 |
|---|---|---|
| 0 | 0x00 | BER 保留 |
| 1 | 0x01 | BOOLEAN |
| 2 | 0x02 | INTEGER |
| 3 | 0x03 | BIT STRING |
| 4 | 0x04 | OCTET STRING |
| 5 | 0x05 | NULL |
| 6 | 0x06 | OBJECT IDENTIFIER |
| 7 | 0x07 | ObjectDescripion |
| 8 | 0x08 | EXTERNAL,INSTANCE OF |
| 9 | 0x09 | REAL |
| 10 | 0x0A | ENUMERATED |
| 11 | 0x0B | EMBEDDED PDV |
| 12 | 0x0C | UFT8String |
| 13 | 0x0D | RELATIVE-OID |
| 14 | 0x0E | 保留 |
| 15 | 0x0F | 保留 |
| 16 | 0x30 | SEQUENCE,SEQUENCE OF |
| 17 | 0x31 | SET,SET OF |
| 18 | 0x12 | NumericString |
| 19 | 0x13 | PrintableString |
| 20 | 0x14 | TeletexString,T61String |
| 21 | 0x15 | VideotexString |
| 22 | 0x16 | IA5String |
| 23 | 0x17 | UTCTime |
| 24 | 0x18 | GeneralizedTime |
| 25 | 0x19 | GraphicString |
| 26 | 0x1A | VisibleString,ISO646String |
| 27 | 0x1B | GeneralString |
| 28 | 0x1C | UniversalString |
| 29 | 0x1D | CHARACTER STRING |
| 30 | 0x1E | BMPString |
| 31 | 0x1F | 保留 |
Length
BER 编码中 Length 表示 Value 部分所占八位组的个数
有两大类:定长方式(DefiniteForm)和不定长方式(IndefiniteForm)
定长方式
定长方式中,按长度是否超过 127(则 7 个位的存储范围),分为短、长两种形式(则用第 8 位来区分):
| 实际长度 | Tag | Length4Length | Length | Value |
|---|---|---|---|---|
| 0~127 | Tag | NULL | 0x00~0x7F | Value |
| 128~256^126-1 | Tag | 0x80+n | n 个 Length | Value |
判断方式:第一个 Length 的最高位是否为 1
Example:
Length(1196==0x04AC)
| Length4Length | Length |
|---|---|
| 0x82 | 0x04 0xAC |
不定长方式
| Tag | Length | Value | End |
|---|---|---|---|
| Tag | 0x80 | Value | 0x00 0x00 |
Length 所在八位组固定编码为 0x80,但在 Value 编码结束后以两个 0x00 结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息给对方。
This post is licensed under CC BY 4.0 by the author.