ASN1BER编解码系统与设计ASN1编码规则详解全面最经典.docx
《ASN1BER编解码系统与设计ASN1编码规则详解全面最经典.docx》由会员分享,可在线阅读,更多相关《ASN1BER编解码系统与设计ASN1编码规则详解全面最经典.docx(34页珍藏版)》请在冰豆网上搜索。
ASN1BER编解码系统与设计ASN1编码规则详解全面最经典
基于ASN.1BER规约的编解码系统设计
非常高兴你能来到小弟的XX文库,您到此地想必是想更多的了解ASN.1BER编码规则吧。
兄弟我大学毕业设计就是有关ASN.1BER编码规则的,电脑里也还存有当时做的系统。
这个文档就是毕业论文的一部分,上传的理由很简单目的就是对ASN.1BER编码规则有个大致的了解!
dengkai-crossfire.taobao./
次数达2次以上者,并给与好评!
(然后联系我的淘宝旺旺,兄弟就把手中ASN.1BER编解码系统双手奉上。
给大家此系统的目的是让大家能更好的了解ASN.1BER编码规则,千万别用来当毕业设计!
到时被老师发现了就不好办了,呵呵!
(当然了,兄弟我能力有限,此毕业设计还存在不足之处)时间久了自己忘得也差不多了,希望发给大家后,好好学习学习!
让!
文档推荐:
ASN.1编码规则详解(最全最经典)wenku.baidu./view/e735ea0bf12d2af90242e6d4.html?
st=1
第4章ASN.1BER编码规则
4.1ASN.1BER数据值的编码结构
BER(BasicEncodingRules)是ASN.1中最早定义的编码规则,在讨论详细编码规则时,我们是基于正确的抽象描述上。
BER传输语法的格式一直是TLV三元组也可以认为是(见图4-1)。
TLV每个域都是一系列八位组,对于组合结构,其中V还可以是TLV三元组(见图4-2)。
BER传输语法是基于八位组的,自定界的编码,因为其中L明确界定了八位组的长度。
图4-1基本编码结构
图4-2组合结构的编码
ASN.1BER数据值的编码主要包含4个部分:
标识符八位位组、长度八位位组、容八位位组以及容结束八位位组。
(见图4-3)
图4-3替换结构编码
除非长度八位位组的值需要出现容结束八位位组,否则该容结束八位位组不应出现,也就是说只有前面三个部分。
4.1.1标识符八位位组
标识符八位位组应对数据类型的ASN.1标签(类和编号)进行编码,对于编号围在0~30(包括0和30)的标签,标识符八位位组应由如下单个八位位组编码而成:
(1)位8和位7应编码为用来表示规定的标签类;(见表4-1))
(2)位6应为0或1,若编码是原始编码,则位6置为0,若编码是结构化编码,则位6置为1;(见图4-4)
图4-4标示位八位位组
(3)位5至位1应把标签编号编码为二进制整数,位5是最高有效位。
表4–1标签类编码
标签类
位8
位7
通用
0
0
应用
0
1
上下文特定
1
0
专用
1
1
按照上面的规则,位6因为0或1。
位5至位1应编码为‘00000’B~‘11111’B的任意一个二进制的,这里所指的是低标签编号。
4.1.2长度八位位组
长度八位位组有两种形式,确定形式和不定形式。
如果是原始编码,则发送器应使用确定形式;若果是结构化编码且都是立即可用的,则发送器可以使用二者之一作为发送器的一个选项;如果是结构化编码且不都是立即可用的,则发送器应使用不定形式。
对于确定形式,长度八位位组应由一个或多个八位位组组成,并应表示使用短形式或长形式作为发送器一个选项的容八位位组中的八位位组数。
这里必须强调八位组中的八位位组数小于或等于127时,仅使用短形式。
在短形式中,长度八位位组应由单个八位位组组成,其中位8为0,位7至位1把容八位位组(它们可能是0)中的八位位组数编码为无符号二进制整数,以位7为最高有效位。
例如:
L=32的编码为0100100B
在长形式中,长度八位位组应由一个初始八位位组和一个或多个后继八位位组组成,初始八位位组应编码如下:
(1)位8因为1;
(2)位7至位1应把长度八位位组中的后继八位位组数编码为无符号二进制整数,以位7为最高有效位。
(3)应不使用值11111111B,引入这个限制是为了将来可能的扩展。
第1个后继八位位组的位8至位1,后随第2个后继八位位组的位8至位1,依次后随更后面八位位组的位8至位1,直至并包含最后1个后继八位位组,应是等于容八位位组中八位位组数的无符号二进制整数的编码,以第1个后继八位位组的位8为最高有效位。
例:
L=201 可编码为
10000001B
11001001B
对于不定形式,长度八位位组指示容八位位组由容结束八位位组来终止,并应由单个八位位组组成。
单个八位位组的位8应置为1,位7至位1置为0。
若使用该长度形式,则应在容八位位组之后的编码中出现容结束八位位组。
4.1.3容八位位组
容八位位组应由0个1个或多个八位位组组成,并且按编码后续各条规定的数据值。
4.1.4容结束八位位组
若长度按不定形式的规定编码,则应出现容结束八位位组,否则应不出现。
容结束八位位组应由两个值为0的八位位组组成。
容结束八位位组可被认为是值的编码,其标签为通用类的,形式为原始编码,标签号为0.且容不存在。
(见表4-2)
表4-2
容结束八位组
长度
容
00
00
无
4.2简单数据类型的编码
4.2.1布尔值的编码
布尔值的编码应是原始编码容八位位组由单个八位位组组成。
若布尔值是FALSE,则八位位组应为0;若布尔值是TRUE,则八位位组应为任意非0值,作为发送器的一个选项。
布尔类型的BER编码(只能以原始方式编码)如图4-5和图4-6所示。
其中值为TRUE时,可以编码为图4-6中的(a)或(b)。
图4-5布尔值为FALSE的编码
(a)短长度值编码(b)长长度值编码
图4-6布尔值为TRUE的编码
4.2.2空值的编码
空值的编码应是原始编码。
容八位位组应不包含任何八位位组,且只有一个值,其BER编码如图4-7所示。
图4-7空类型的编码
4.2.3整数值的编码
整数值的编码应是原始编码,容八位组由一个或多个八位位组组成。
如整数值编码的容八位位组由多个八位位组组成,则第一个八位位组的各个位和第二个八位位组的bit8应不全为1并且也应不全为0。
另外,容八位位组应是等于整数值的对应的2的补码的二进制数,其组成是由第一个八位位组的bit8至bit1,后随第二个八位位组的bit8至bit1,依次后随每个八位位组的bit8至bit1,直至到并包含容八位位组的最后一个八位位组。
整数类型也是只能以原始方式进行BER编码。
这里需要分编、解码两个过程和整数、负数两种情况进行讨论。
(1)编码过程如图4-8所示。
对于正数,若果最高位比特位为0则直接编码;如果为1,则在最高比特位之前增加一个全0八位位组。
对于负数,先取绝对值,在取反,最后加1。
图4-8整型的编码过程
(2)解码过程如图4-9所示。
图4-9整型的解码过程
基于前面所述的规则,整数-27066的编码如图4-10所示。
图4-10整型的BER编码示例
具体过程:
-27066—>27066—>0110100110111010—>
1001011001000101+1(B)—>1001011001000110
4.2.4枚举值的编码
枚举值的编码应是与之先关的整数值的编码。
值得注意的是它是原始编码。
枚举类型的值按照前面整数值的规则编码。
4.2.5实数值的编码
实数值的编码应是原始编码,具体编码如下:
(1)如果实数为0值,则编码中应没有容八位位组;
(2)对非0实数值,若果抽象值的基数是10,则编码值的基数也应为10;如果抽象值的基数是2,则编码值的基数(B’)应为2、8或16,作为发送器的一个选项。
(3)如果实数值为非0值,那么用于编码的基数应为
(2)所规定的B’。
如果B’是2、8或16,应使用(5)规定的二进制编码。
如果B’是10,则应使用(6)规定的字符编码。
(4)第一个容八位位组的bit8应设置如下:
①如果bit8为1,则使用(5)规定的二进制编码;②如果bit8为0,且bit为0,则使用(6)规定的十进制编码;③如果bit8为0,且bit为1,则按(7)规定的编码一个“SpecialRealValue”。
(5)当使用二进制编码时(bit8为1),如果尾数M是非0则它应由一个符号S、一个非负整数值N以及一个二进制比例因子F来表示即:
,0≤F<4,S=+l或-1。
需要注意的是在某些环境下需要二进制比例因子F,以便将尾数隐含的小数点与本条编码规则所要求的位置对齐。
这种对齐不能总是通过修改指数E来获得,如果用于编码的基数B’是8或16,隐含的小数点只能通过改变指数E分别以3个位或4个位为一步进行移动.因此,可能要求不是0的二进制比例因子的值,以便将隐含的小数点移动到所要求的位置。
如果S为-1.第1个容八位位组的bit7应为1.否则为0。
第1个容八位位组的bit6至bit5应编码基数B’的值如表4-3所示,
表4-3实数值编码示例
bit6至bit5
基数
00
基数为2
01
基数为8
10
基数为16
11
为本部分将来做保留
第1个容八位位组的bit4至bit3应把二进制比例因子F的值编码为无符号二进制整数。
第1个容八位位组的bit2至bitl应编码指数格式如下:
①如果bit2至bit1为00,那么第2个容八位位组把指数的值编码为2的补码的二进制数;
②如果bit2至bit1为01,那么第2个和第3个容八位位组把指数的值编码为2的补码的二进制数;
③如果bit2至bit1为10,那么第2、第3和第4个容八位位组把指数的值编码为2的补码的二进制数;
④如果bit2至bit1为11,那么第2个容八位位组编码用于编码指数的值的八位位组的数,假定为x,(为无符号二进制数),并且第3个直到第(x加3)个(包括二者)容八位位组将指数的值编码为2的补码的二进制数;x的值应至少为1.发送指数的最前9位应不全为0或不全为1。
剩余的容八位位组将整数N的值编码为无符号二进制数。
需要注意:
①对于非正BER,没有尾数的浮点常规化的需求.这允许实现者发送包含尾数的八位位组,而不用在存中对尾数执行移位功能。
在正则编码规则和非典型编码规则中,规定了常规化,并且尾数(除非它是0)需要重复地移位直至最低有效位为l;
②实数数字的这种表示与通常用在浮点硬件中的格式有很大不同.但实数数字的表示已设汁成能容易地与这种格式来回地转换。
(6)当使用十进制编码时(bit8至bit7为00),按SJ/Z9047--1987中使用的术语,跟在第1个容八位位组后的所有容八位位组形成作为发送器一个选项的字段长度,并且按照SJ/Z9047--1987进行编码。
SJ/Z9047--1987数字表示的选择由第1个容八位位组的bit6至bit1如表4-4所示,
表4-4SJ/Z947—1987数字表示的选择规定
bit6至bit1
数字表示
000001
SJ/Z9047NR1形式
000010
SJ/Z9047NR2形式
000011
SJ/Z9047NR3形式
bit6至bit1中剩余的值为本部分而保留。
(7)当“SpecialRealValues”被编码(bit8至bit7为01)时,应只有一个容八位位组,值如下:
01000000值为PLUS-INFINITY
01000001值为MINUS-INFINITY
实数类型的BER编码示例如图4-11所示。
图4-11实数类型的编码示例
4.2.6位串值的编码
位串值的编码应是原始编码或结构化编码,并作为发送器的选项。
采用原始编码方式,对'1011011101011'B的编码规则如图4-12所示,
图4-12
注意在'1011011101011'B前增加了一个八位组,取值为0到7,表示这个值最后补位的个数。
由发送方决定补位采用0还是1。
如果BITSTRING的值为空,则编码时,长度为1,补充的八位组为全0。
如果位串的值为空,则编码时,长度为1,补充的八位位组全为0。
如图4-13所示,
图4-13
结构化编码是在发送时,有部分编码还不能确定时采用的,图4-14给出了位串值‘1011011101011’B的编码。
图4-14
注意Length部分采用的是不定长编码。
4.2.7八位位串值的编码
与位串值类似,但是不需要增加表示补充个数的八位位组。
4.3构造类型的编码
4.3.1序列值的编码
序列值的编码应是结构化编码。
容八位位组中应由ASN.1序列类型定义中列出的每个类型的一个数据值的完整编码的组成。
除非引用的类型带有关键字OPTIONAL或DEFAULT,否则这些编码按定义中的次序出现。
引用的类型带有的关键字OPTIONAL或DEFAULT,其数据编码值可以出现,但不是必要的,若出现,则它应在ASN.1定义的类型编码懂得相应点出现。
对如下定义:
vSEQUENCE{ageINTEGER,singleBOOLEAN}:
:
=
{age24,singleTRUE}
其BER编码如图4-15所示,
图4-15SEQUENCE编码示例
4.3.2集合值的编码
容八位位组中应由ASN.1序列类型定义中列出的每个类型的一个数据值的完整编码的组成。
除非引用的类型带有关键字OPTIONAL或DEFAULT,否则这些编码按发送者选定的次序出现。
引用的类型带有的关键字OPTIONAL或DEFAULT,其数据编码值可以出现,但不是必要的。
集合中的数据值的次序不重要,对传送期间的次序没有限制。
集合类型的编码与序列类似,但成员顺序由发送者决定。
4.3.3单一序列值的编码
单一序列值的编码应是结构化编码。
容八位位组应由0个、1个或多个在ASN.1中定义中列出的数据类型值的完整编码组成。
数据值的编码的次序应与被编码的的单一序列值中的数据值的次序相同。
对定义为tripletSEQUENCEOFINTEGER:
:
={2,6,5}的BER编码如图4-16所示,
图4-16SEQUENCEOF编码示例
4.3.4单一集合值的编码
单一集合值的编码应是结构化编码。
容八位位组应由0个、1个或多个在ASN.1中定义中列出的数据类型值的完整编码组成。
编码及后续解码时,不必保持数据值的次序。
单一集合类型的编码与单一序列类似。
4.4本章小结
ASN.1BER的数据值的编码,一般有三部分组成:
标识符八位位组,长度八位位组和容八位位组。
本章从这三部分出发,先后简单介绍了几种简单数据值类型和结构化数据值的编码规则。
本章介绍的简单类型有:
布尔值,整数值,枚举值,实数值,位串值,八位位串值和空值;构造类型有:
序列值,单一序列值,集合值,单一集合值。
本章还着重介绍了各种数据值的编码算法,按照ASN.1BER的规则,对数据值进行编码,为后续章节的实现过程,奠定了理论基础。
第5章基于ASN.1BER规则的解码实现
前面几章对ASN.1语法定义及ASN.1BER规则做了详细的介绍,分析了布尔值,空值,整数值,枚举值,实数值,位串值,八位位串值,序列值,单一序列值,集合值,单一集合值总共11种数据值编码规则。
本章重点介绍各数据值解码的实现,画出其流程图,并给出测试结果截图。
5.1布尔值的解码
布尔值的码流由三个部分组成,由标识符,数据长度和容。
其中标识符和数据长度都是固定的都为0116,所以布尔值解码时,只要判断布尔值的容(Value)是FF16还是0016,如果是FF16则解码为TRUE,是0016则解码为FAlSE。
布尔值的解码流程图如图5-1所示。
图5-1布尔值的解码流程图
按照图5-1流程图的思想完成编写布尔值的解码程序。
布尔值解码程序的运行结果截图如图5-2和5-3所示,其中布尔值码流中的标识符,数据长度和容都是以十六进制形式来表示。
5-2布尔值为TURE的解码结果截图
5-3布尔值为FALSE的解码结果截图
5.2空值的解码
空值是ASN.1所有数据值中最简单的一种。
其标志符编码为:
0516,数据长度为固定值:
0016,容为空。
所以要实现对空值:
05160016的解码,只需判断其标识符是否为0516就可以了。
空值解码程序的流程图如图5-4所示。
图5-4空值解码流程图
图5-5空值的解码结果截图
按照图5-4流程图的思想完成编写空值的解码程序。
空值解码程序的运行结果截图如图5-5所示,其中空值码流中的标识符和数据长度都是以十六进制形式来表示。
空值最特别的一点就是其码流中容项为空。
5.3整数值的解码
整数值的解码的码流由三部分组成:
标识符,数据长度和容。
ASN.1BER编码规则中,各种数据值的标识符都是固定的。
输入一个整数码流,首先要判断其容第一个八位组的最高位是为0还是1。
如果容第一个八位组的最高位为0,这个码流解码的结果应是一个正整数或0,直接将容二进制字符串转化为十进制整数就可以。
若容第一个八位组的最高位为1,这个码流解码的结果应是一个负整数,先将容二进制字符串-1,其次各位取反,在将取反后的二进制字符串转化为十进制整数,在将这个整数取反就是最后的解码结果。
具体过程如图5-6所示。
5-6整数值的解码流程图
这里容二进制字符串转化为十进制整数是通过循环取剩余字节来实现的。
按照图5-6流程图的思想完成编写整数值的解码程序。
在这里给出4个整数值的解码结果截图,分别是0,128,-128以及123456789四个整数值解码结果截图。
整数值解码程序的运行结果截图如下图所示。
图5-7整数值0的解码结果截图
图5-8整数值123456789的解码结果截图
图5-9整数值128的解码结果截图
图5-10整数值-128的解码结果截图
若整数值编码的容八位位组由多个八位位组组成,则第1个八位位组的各个位和第2个八位位组的位8:
应不全为1并且应不全为0,图5-9与图5-10验证了这条编码规则。
5.4枚举值的解码
枚举值的解码与整数值的解码非常类似,其具体解码程序跟整数值解码函数可以一样,唯一的区别在于它们在通用类中的标签号不同,整数值的标识符为0916,而枚举值的标识符为0A16。
下面给出枚举值128的解码程序运行结果,枚举值的解码程序行结果截图如图5-11所示。
图5-11枚举值128的解码结果截图
5.5位串值的解码
位串值的标识符是0316。
要实现位串值码流的解码,首先就是要要知道码流的数据长度,在容二进制字符串中,第一个八位组是用来标记二进制位串值所补0的个数(8的整数倍),其围从0016—0716。
在用后继八位组减去所添加0的个数,就是所解码的位串值结果。
具体过程如图5-12所示。
按照图5-12流程图的思想完成编写位串值的解码程序。
在此给出两个位串值的解码结果截图:
一个是‘1001110100011010’B的解码,如图5-13所示。
另一个是‘10011101000110’B的解码,如图5-14所示,它们最主要的区别在于末尾是否有添加0,使得二进制字符串为8的整数倍。
在这里需要指出的一点是,位串值编码时,输入的格式有两种:
二进制形式和十六值形式。
这个ASN.1BER编解码系统中,在位串值解码时,最后的结果只能是二进制的字符串。
所以,在连接两台电脑实现通讯编解码的过程中,如果在电脑A中输入的是十六进制的位串值,在电脑B中解码的结果则为二进制位串值,虽然它们的表现的形式不一样,但归根结底还是指的是同一个数。
图5-12位串值解码流程图
图5-12位串值‘1001110100011010’B解码结果
5-13图5-12位串值‘10011101000110’B解码结果
5.6八位位串值的解码
八位位串值的解码和位串值的解码相似,而且比二者比较前者还更简单。
因为它输入的字符串转换为二进制后都是8的整数倍,所以这里就不存在容补充八位组,解码时只要将八位位串值码流中的容字符串取出来就可以了,具体过程如流程图5-14所示。
图5-14八位位串值解码流程图
按照图5-14流程图的思想完成编写八位位串值的解码程序。
此ASN.1BER编解码系统中,八位位组串值的输入形式是十六制形式,解码结果也为十六制形式。
八位位串值解码程序的运行结果截图如图5-15所示。
图5-15八位位串值解码结果截图
5.7实数值的解码
实数的解码比较复杂,需要考虑的情形也比其它简单类型的多。
无穷大,无穷小,0值,这三个数值的码流都是跟定的。
实数值的标识符是0916。
由于编码是采用的是二进制方法统一编码,所以解码时采用的是以2作为基数,也就是说控制字节的bit6和bit5为00。
图5-16为实数解码函数的流程图。
当输入一串实数值码流是,首先判断它是否为正负无穷大,如果是对其进行解码,码流解码结束,如果不是在对具体实数进行解码。
先读取容的第一个八位组,看bit7是0还是1,是0说明这个实数是整数,是1说明这个实数是负数,容的第二个八位组中是其指数的大小,后继八位组就是尾数,知道指数、尾数正负号,就可以对码流实现解码。
程序运行结果如图5-17和5-18所示。
下面就以5-18中码流为例来说明:
码流:
090380FCC4它是以十六进制形式来表示的。
09是它的标识符,03代表数据容的长度,80是容的第一个八位位组也称为控制字节,说明这个解码的实数是个正数。
接下来的一个八位组为指数,剩下的八位组就是尾数。
指数:
FC转化为二进制是‘11111100’B,因其最高位是bit8=1,将其减1在各位取反,的‘00000100’B,指数为4。
尾数:
C4转化为二进制‘11000100’B,所以尾数为0.11000100,这里尾数的定义与ASN.1BER规则稍有点不同,它是将小数点移到最高位为0的后面,而不是1.10001000,
,也就是1100.0100,最后分别将正数部分和小数部分转化为十六进制就是最终的解码结果。
5-16实数值的解码流程图
5-17实数值为-12.25的解码结果
5-18实数值为12.25的解码结果
5.8构造类型解码
构造类型的数据值包括:
序列值、单一序列值、集合值、单一集合值。
本小节讨论上述四种数据值类型的解码。
构造类型数据值的解码,实际上是对简单数据值解码函数的调用,完成指定的简单数据值解码。
5.8.1序列值的解码
序列值的编码是结构化编码,其标志符为3016。
序列值码流容中可以包含其其它各种简单类型码流。
在编写序列值解码程序之前,先完成对布尔值,空值,整数值等数据值解码函数的封装,序列值解码程序只需要识别序列值码流中要解码的各种简单数据类型,在调用相应的数据值的解码处理函数,就可以完成序列值的解码。
(1)数据值类型定义
为了使编码输入和解码输出结果更直观,这里给数据值类型做了如下定义:
NULL:
:
=表明后面的数据值类型是空值;
BOOLEAN:
:
=表明后面的数据值类型是布尔值;
INTEGER:
:
=表明后面的数据值类型是整数值;
ENUMERATED:
:
=表明后面的数据值类型是枚举值;
REAL:
:
=表明后面的数据值类型是实数值;
BITSTRING:
:
=表明后面的数据值类型是位串值;
OCTETSTRING:
:
=表明后面的数据值类型是八位位组串值;
SEQUENCE:
:
={}
SEQUEN