ASN.1 常用类型 编码详解 入门

文章目录

    • 编码结构
      • 标识符 Identifier
      • 长度 Length
        • 短形式
        • 长形式
      • 内容 Contents
    • 基本类型
      • 布尔类型 BOOLEAN
      • 整形 INTEGER
      • 实数 REAL
      • 枚举类型 ENUMERATED
        • 二进制的编码
        • 十进制的编码
        • 特殊实数编码
      • 比特串 BIT STRING
      • 字节串 OCTET STRING
      • 空值 NULL
      • 序列 SEQUENCE
      • 数组 SEQUENCE-OF
      • 集合 SET
      • SET-OF
      • 选择 CHOISE
    • 结束
    • 参考文献

编码结构

下面说明的均为primitive类型,constructed类型不做讨论。

BER – Basic encoding rules 基础编码规则

组成部分:

  1. 标识符(Identifier)
  2. 长度(Length)
  3. 内容(Contents)

编码结构如下图所示:
ASN.1 常用类型 编码详解 入门_第1张图片

标识符 Identifier

标识符就是表示这个数据结构的类型。

标识符占用 1 字节(byte)

标识符结构如下:
ASN.1 常用类型 编码详解 入门_第2张图片

标识符字节各位(bit)详解:

  1. 第8 - 7位表示这个标签的类别。类别如Table 1所示,一般情况下使用Universal类型,就是00
  2. 第6位
    • 0 表示primitive标签类型
    • 1 表示constructed标签类型
  3. 第5 - 1位表示为一个无符号数字,这个数字为这个标签的类型数字。这个数字的最高有效为第5位。

ASN.1 常用类型 编码详解 入门_第3张图片

此处所描述的结构只适用于类型小于30种的定义,如果类型超过30就需要使用 high tag number方式的数据结构,此处不做描述。

长度 Length

长度就是表示Contents字节数量。

长度的结构有两种构成方式,按照Content实际的长度(字节数量)来划分:

  • 短形式,Contents长度小于等于 (<=) 127。
  • 长形式,Contents长度大于 (>) 127。

短形式

Contents长度小于等于 (<=) 127

长度占用 1 字节(byte)

ASN.1 常用类型 编码详解 入门_第4张图片

短形式字节各位(bit)详解:

  1. 第8位固定值0
  2. 第7 - 1位表示一个无符号数字,表示Contents中字节数量,其中最高有效位为第7位。(该数字可能为0)

示例:

Length = 38 二进制编码为 0010 0110

长形式

Contents长度大于 127。

长形式的长度由一个或多个子字节构成。
ASN.1 常用类型 编码详解 入门_第5张图片

长形式详解:

  1. 第1子字节
    • 第8位固定值1
    • 第7 - 1 位表示一个无符号数字,表示长度的子字节的数量,其中最高有效位为第7位。
    • 第一个字节不允许出现 1111 1111的情况。
  2. 第1子字节之后的字节,表示一个无符号数字,表示Contents中字节数量,其中最高有效位为第1子字节之后的第一个字节的第8 位。

示例:

Length = 201 二进制编码为

1000 0001
1100 1001

内容 Contents

Contents表就是这个数据结构所要表示的值。它由0到多个字节构成,内容的值应该按照对应类型进行对应的编码。

基本类型

布尔类型 BOOLEAN

标识符为:0x01

固定长度:1 (字节)

FALSE - 单字节中所有位为0,0x00

TRUE - 单字节中所有位为1,0xFF

示例:

TRUE的布尔值编码为:
ASN.1 常用类型 编码详解 入门_第6张图片

整形 INTEGER

标识符为:0x02

整形类型的Contents由0到多个字节构成。

如果整形的值(Contents中的内容)编码数量超过一个字节,那么值的第1个字节(byte)和第二个字节的第8位(bit)应该是下面情况:

  • 两者都不应全为1
  • 两者都不应全为0

整形类型的Contents中的字节因为所表示数字的二进制 补码 表示。

正数的补码:等于本身。

如: 1 - 0000 0001 的补码为 0000 0001

负数的补码:符号位不变,其它位按位取反,最后再加1

如: -1 - 1000 0001 的补码为 1111 1111

示例

-1 可以表示为:
ASN.1 常用类型 编码详解 入门_第7张图片
128 可以表示为:
ASN.1 常用类型 编码详解 入门_第8张图片

实数 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的计算方式如下:

ASN.1 常用类型 编码详解 入门_第9张图片

有时需要调整系数F以便使得尾码达到编码对齐规则。

实数的二进制编码
Contents第一个字节编码规则:

  1. bit 8 固定值1
  2. bit 7
    • S为-1时为1
    • S为+1时为0
  3. bit 6 - 5 代表基于什么进制,如 Table 2 所示。
  4. bit 4 - 3 表示二进制系数F
  5. 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位不能全为01

ASN.1 常用类型 编码详解 入门_第10张图片
除去上述描述的字节之后,Contents剩余的所有字节用于表示整数N的无符号二进制编码。

十进制的编码

Contents的第一个字节的bit 8 to 7 为00Contents中除第一个字节之外的所有内容构成一个Field

Field《ISO 6093》 有具体描述,包括长度和编码。

Contents的第一个字节的bit 6 到 1位有以下可选值:
ASN.1 常用类型 编码详解 入门_第11张图片

特殊实数编码

Contents的第一个字节的bit 8 to 7 为01,那么Contents仅有一个字节,它的值可以使下表
ASN.1 常用类型 编码详解 入门_第12张图片

比特串 BIT STRING

标识符为:0x03
ASN.1 常用类型 编码详解 入门_第13张图片
比特串的Contents包含一个初始(Initial)字节,它的后面接上0到多个字节。

比特串所表示的值,按照比特串的顺序,从头到尾,每个8bit作为一个字节,依次排列,最后一组不足8位,就补0以达到一个字节。

示例
ASN.1 常用类型 编码详解 入门_第14张图片

Contents中的初始字节,是一个无符号的二进制编码的数,最低有效位为第1位。用来表示最后一个字节中补0的数量。初始化字节的范围为:[0, 7]。

如果 字节串为空,那么不应该有任何子字节,初始化字节为0。

结构示例:

比特串 0x0A3B5F291CD 的二进制编码为:

ASN.1 常用类型 编码详解 入门_第15张图片

Contents第一个字节的0x04表示补充了4个零。

字节串 OCTET STRING

标识符为:0x04

字节串在Contents中按照字节串的值的原始顺序,使用0或多个字节,来表示字节串的值。

示例:

字节串 0x00B701 二进制编码为:
ASN.1 常用类型 编码详解 入门_第16张图片

空值 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
}

对应的二进制编码为:
ASN.1 常用类型 编码详解 入门_第17张图片

数组 SEQUENCE-OF

标识符为:0x30

数组中的元素ASN.1类型都是同种类型的。

数组的Contents中包含0到多个定义好的的ASN.1值的完整编码,并且按照它们原先在序列中的顺序出现。

示例

BOOLEAN类型的数组定义:

 SEQUENCE OF BOOLEAN

值为:

{
	TRUE, FALSE, TRUE
}

对应的二进制编码为:

ASN.1 常用类型 编码详解 入门_第18张图片

集合 SET

标识符为:0x31

集合的Contents中包含,除了使用OPTIONAL或DEFAULT类型修饰的关键字之外,序列中含有每一个子项的ASN.1的完整编码,并且按照它们原先在序列中的顺序出现。

示例

集合的值为:

{
	TRUE, 
	777,
	0x01020304 --bitString
}

对应的二进制编码为:
ASN.1 常用类型 编码详解 入门_第19张图片

SET-OF

标识符为:0x31

SET-OF 基本与 “数组 SEQUENCE-OF ” 一致,在此不做描述。

选择 CHOISE

标识符为:无

选择类型中表示的字段中,该字段可能有多重不同的类型来表示。

选择类型的编码应该与所选中的值的编码相同。

示例

定义一个名为parameter 选择为

parameter CHOISE {
	integerType 				INTEGER,
	booleanType				BOOLEAN
}

parameter 的值为

parameter  booleanType TRUE

对应的二进制编码为:
ASN.1 常用类型 编码详解 入门_第20张图片

结束

本次介绍的是常用的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

[2] ITU .X.690 . ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER) [S] . 2015-08

[3] bj-sys . https://www.obj-sys.com/asn1tutorial/node10.html

你可能感兴趣的:(标准解读)