图文解析ASN.1中BER编码:结构类型、编码方法、编码实例

本文将详细介绍ASN.1中的BER编码规则,包括其编码机制数据类型表示、以及如何将复杂的数据结构转换为二进制数据。通过本文的阅读,读者将对ASN.1中的BER编码有一个全面的理解。


目录

一.引言

二.BER编码基本结构

▐ 1. 类型域(Type)

示例一

示例二

▐ 2. 长度域(Length)

示例一

示例二

▐ 3. 内容域(Value)

布尔型(BOOLEAN)

整型(INTEGER)

位串(BIT STRING)

字符串(OCTET STRING)

NULL

对象标识符(OBJECT IDENTIFIER)

序列(SEQUENCE)


一.引言

在现代通信和信息技术领域,数据的精确表示和高效传输是至关重要的。ASN.1(Abstract Syntax Notation One)作为一种国际标准化组织(ISO)和国际电信联盟(ITU)制定的国际标准,提供了一种抽象的方法来描述、编码、解码和传输数据。ASN.1的核心组成部分之一是BER(Basic Encoding Rules),它定义了一种将ASN.1数据结构转换为二进制形式的编码规则。

BER编码不仅确保了数据的一致性和互操作性,而且通过其灵活的编码机制,支持了广泛的数据类型和结构。从简单的整数和字符串到复杂的数据结构,如序列和集合,BER编码都能够提供一种标准化的表示方法。这使得不同系统和应用程序能够无缝地交换数据,无论它们运行在何种平台或使用何种编程语言。


二.BER编码基本结构

BER(Basic Encoding Rules)是一种用于描述ASN.1(Abstract Syntax Notation One)数据的编码规则。BER编码广泛用于网络协议和数据交换标准,例如SNMP和LDAP。BER编码使用一种TLV(Type-Length-Value)的结构方法编码。

即,BER编码的基本结构由以下三个部分组成:

  • 类型域(Type)
  • 长度域(Length)
  • 内容域(Value)

其中类型(Type)部分又有三部分组成:

  • 标签类型(Class)
  • 构造类型(P/C)
  • 标签号(Tag)

 就拿C语言的数据结构来说,除了有单一的Int类型,Doubel类型等,还有复杂的自定义类型结构体,对于一种数据结构中包含了其他数据结构的情况,BER编码也对其进行了规定,称之为结构类型。结构类型与一般简单类型的不同如下图:

如图所示,在复杂的结构类型中,他的内容域往往包含了许多简单类型。毕竟结构类型也只是简单类型的复合,因此下午的讲解全部都通过简单类型进行讲解。

我们分别对三部分进行分析: 


▐ 1. 类型域(Type)

在 BER(Basic Encoding Rules)编码中,类型域(Type)用于标识数据的类型和类别。类型域编码包含三个部分:类(Class)、构造类型(PC, Primitive/Constructed)、和标签号(Tag Number)。下面详细说明这三个部分的编码:

类型域结构

类型域是一个字节(8 位)或多个字节(对于较大的标签号)。第一个字节的结构如下:

  • 第8-7位:类(Class)

    • 00:通用类(Universal)

    • 01:应用类(Application)

    • 10:上下文特定类(Context-specific)

    • 11:私有类(Private)

  • 第6位:构造类型(Constructed/Primitive)

    • 0:原始类型(Primitive)

    • 1:构造类型(Constructed)

  • 第5-1位:标签号(Tag Number)

    • 若标签号小于 31(即 0-30),则直接使用这些位表示标签号。

    • 若标签号大于等于 31,则这些位全为 1,并且标签号在后续字节中以一种特殊的方式编码。

笔者这里给出图示如下:

对于标签号,这里在解释一下: 

简单标签号(0-30)

对于标签号在 0 到 30 之间的情况,直接在类型域的第1-5位表示。例如:

  • 通用类(Universal)布尔类型(Boolean):0000 0001,即 0x01

  • 应用类(Application)整数类型(Integer):0100 0010,即 0x42

复杂标签号(>= 31)

对于标签号大于等于 31 的情况,第1-5位全为 1(即 0b11111),并且标签号以基于共占 7 位的块形式在后续字节中表示,每个字节的最高位为 1,表示后续有更多字节;最后一个字节的最高位为 0,表示后面没有字节了。例如:

  • 标签号 31:0b1111 1111 0001 1111,即 0x1F 0x1F

  • 标签号 128:0b1111 1111 1000 0001 0000 0000,即 0x1F 0x81 0x00

示例一

Tag number < 31
yesterdayINTEGER ::=127
        Class = Universal
        P/C = Primitive(简单类型)
        Tag = 2(INTEGER)
        Length =1 byte
        Content =127

按照给出的信息,我们就可以得到如下结论:

类型域值为:00000010(0x02)
长度域值为:01
内容域值为:7F
BER编码为:00000010 0000000101111111
        (02 01 7F)

示例二

Tag number >= 31
OwnInt ::=[APPLICATION 33]IMPLICIT INTEGER 
HillTall Ownint ::= 110
    Class = Application
    P/C = Primitive(简单类型)
    Tag = 33
    Length = 1
    Content = 110

按照给出的信息,我们就可以得到如下结论:

类型值为:01011111 00100001(5F21)
长度值为:1
内容值为:6E(110)
BER编码为:5F 21 01 6E

总结

  • 类型域的前两位表示类(Class),第三位表示构造类型(Primitive/Constructed),第四至第八位表示标签号(Tag Number)。

  • 对于标签号小于 31 的情况,直接使用第1-5位。

  • 对于标签号大于等于 31 的情况,使用多个字节表示,第一字节的第1-5位全为 1,后续字节以 7 位块形式表示标签号。

通过这种编码方式,BER 能够灵活地表示各种数据类型,并确保编码的准确性和可扩展性。


▐ 2. 长度域(Length)

在 BER(Basic Encoding Rules)编码中,长度域用于指示随后的值域(Value)的长度。长度域的编码有主要两种形式:短形式和长形式。下面是对这两种形式的详细说明:

短形式

短形式用于表示长度小于 128 字节(即 0 到 127)的情况。在这种形式中,长度域仅占一个字节。该字节的最高位(第八位)为 0,低七位表示长度的值。例如:

  • 若长度为 5,则长度域为 0000 0101(即 0x05)。

  • 若长度为 127,则长度域为 0111 1111(即 0x7F)。

长形式

长形式用于表示长度大于等于 128 字节的情况。在这种形式中,长度域的第一个字节的最高位(第八位)为 1,低七位表示后续长度字节的个数。例如:

  • 若长度为 128,则长度域为 1000 0001(表示后续有 1 个字节)加上 1000 0000(表示长度为 128),即 0x81 0x80

  • 若长度为 300,则长度域为 1000 0010(表示后续有 2 个字节)加上 0000 0001 0010 1100(即 300),即 0x82 0x01 0x2C

长度不确定

上述俩种情况适合用于长度确定的情况,当长度不确定的时候,长度字节最高位置1,该字节的低7位置0。紧随的字节为内容字节,最后以两个字节 0x00 和 0x00 作为结束标志

图示如下:

示例一

Length < 128
DayOfYear ::= [application 17]IMPLICIT INTEGER
Today DayOfYear ::=128
    Class = Application
    P/C = Primitive
    Tag = 17
    Length = 2
    Content =128

 按照给出的信息,我们就可以得到如下结论:

提示:这里的内容域首位为 1 所有前面要加一个字节的0,后文会讲这部分

类型值:01 0 10001
长度值:0000 0010
内容值:0x00 80
BER编码为:01010001 00000010 00000000 10000000

示例二

Length >= 128
MemoString ::= Octest String( size(256))
memo MemoString ::=“abc...
    Class = Universal
    P/C = Primitive
    Tag = 4
    Length = 256

按照给出的信息,我们就可以得到如下结论:

类型值:00 0 00100(04)
长度值:1000 0010(0x82) 0000 0001 0000 0000(0x0100)
内容值:61 62 63...(”abc...”)
BER编码为:04 82 01 00 61 62 63

总结

  • 对于长度小于 128 的值,使用短形式,只需要一个字节,最高位为 0。

  • 对于长度大于等于 128 的值,使用长形式,首字节的最高位为 1,低七位表示后续字节的数量,这些后续字节组成一个大端整数,表示长度值。

  • 如果长度不确定,长度字节最高位置1,该字节的低7位置0,最后以俩个字节 0x00 和 0x00 作为结束标志

这样,BER 编码能够灵活地表示不同长度的数据,确保编码的效率和可扩展性。


▐ 3. 内容域(Value)

在 BER(Basic Encoding Rules)编码中,内容域(Value)包含实际的数据信息,其编码方式取决于数据的类型。不同数据类型有不同的编码规则。以下是一些常见数据类型的编码方式:

布尔型(BOOLEAN)

布尔型值使用一个字节表示:

  • TRUE 编码为 0xFF

  • FALSE 编码为 0x00

整型(INTEGER)

整型值以大端顺序(高字节在前)编码,使用最少的字节数来表示值。如果最高有效位为 1,则需要在前面加一个 0x00 以避免符号扩展。例如:

  • 0 编码为 0x00

  • 127 编码为 0x7F

  • 128 编码为 0x00 0x80

  • -1 编码为 0xFF

位串(BIT STRING)

位串由一个初始字节和实际数据组成。初始字节表示未使用的位数。实际数据按字节顺序排列。例如:

  • 0x01101011(假设全用)编码为 0x00 0x6B

  • 0x01101010(未使用1位)编码为 0x01 0x6A

字符串(OCTET STRING)

字符串(八位字节串)按字节顺序直接编码。例如:

  • "Hello" 编码为 0x48 0x65 0x6C 0x6C 0x6F

NULL

NULL 值没有内容,其长度为 0。因此,NULL 值的编码只是标记和长度,值为空。例如:

  • NULL 编码为 0x05 0x00

对象标识符(OBJECT IDENTIFIER)

对象标识符使用变量长度编码。前两个节点由 (X * 40) + Y 公式表示,后续节点使用基于 7 位的块形式编码,最高位为 1 表示有后续字节。例如:

  • 1.2.840.113549 编码为 0x2A 0x86 0x48 0x86 F7 0x0D(1*40 + 2 = 42, 840 = 0x86 0x48, 113549 = 0x86 0xF7 0x0D)

序列(SEQUENCE)

序列包含一个或多个元素,每个元素按其类型编码,然后依次排列。例如,一个包含一个整数和一个字符串的序列:

  • 整数:42 编码为 0x02 0x01 0x2A

  • 字符串:"Hi" 编码为 0x04 0x02 0x48 0x69

整个序列编码为:0x30(标记) 0x07(长度) 0x02 0x01 0x2A(整数) 0x04 0x02 0x48 0x69(字符串)

总结

值域的编码方式根据数据类型的不同而不同,具体编码规则如下:

  • 布尔型:使用一个字节表示 TRUE 或 FALSE。

  • 整型:大端顺序,使用最少的字节数。

  • 位串:一个初始字节表示未使用的位数,后跟实际数据。

  • 八位字节串:直接按字节顺序编码。

  • NULL:无内容,长度为 0。

  • 对象标识符:使用变量长度编码,前两个节点压缩表示,后续节点基于 7 位块编码。

  • 序列:包含一个或多个元素,按其类型编码后依次排列。

通过这些编码规则,BER 能够灵活且高效地表示各种类型的数据。


以上便是BER编码的基础结构和编码方法,掌握了上述种种就可以构建基本的BER编码,而更加复杂的编码也只是多个简单的编码复合而成。研究BER编码对于以下应用场景也有着重要的作用:

  1. 网络协议:BER编码在网络协议中用于确保数据在不同系统和平台之间传输时的准确性和完整性。

  2. 安全协议:在安全领域,BER编码用于加密和解密过程中,确保数据的安全传输,如在SSL/TLS协议中。

  3. 数字证书:BER编码用于数字证书的编码,这是公钥基础设施(PKI)的关键组成部分,广泛应用于身份验证和数据加密。

  4. 数据库:在数据库系统中,BER编码用于存储和检索结构化数据,提高数据的组织和访问效率。

  5. 数据存储:BER编码在数据存储解决方案中用于优化数据的存储格式,减少存储空间的使用。

  6. 图像和视频传输:在多媒体领域,BER编码可以用于图像和视频数据的高效传输和存储。




 本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

摘 要 I ABSTRACT II 第1章 绪论 1 1.1 ASN.1概述 1 1.2 ASN.1系列标准 1 1.3 ASN.1编解码的应用与发展前景 2 1.4论文章节结构组织 2 第2章 ASN.1词汇及词法约定 3 2.1 字符集 3 2.2 词项 3 2.3 本章小结 4 第3章 ASN.1数据类型定义 5 3.1 简单数据类型 5 3.1.1 布尔类型 5 3.1.2 空类型 5 3.1.3 整数类型 6 3.1.4 枚举类型 6 3.1.5 实数类型 7 3.1.6 位串类型 7 3.1.7 八位位串类型 8 3.2构造类型 8 3.2.1 序列类型 8 3.2.2 单一序列类型 9 3.2.3 集合类型 10 3.2.4 单一集合类型 10 3.3 本章小结 11 第4章 ASN.1BER编码规则 12 4.1 ASN.1BER数据值的编码结构 12 4.1.1标识符八位位组 12 4.1.2长度八位位组 13 4.1.3内容八位位组 14 4.1.4内容结束八位位组 14 4.2简单数据类型编码 14 4.2.1 布尔值的编码 14 4.2.2 空值的编码 14 4.2.3 整数值的编码 15 4.2.4 枚举值的编码 16 4.2.5 实数值的编码 16 4.2.6 位串值的编码 18 4.2.7 八位位串值的编码 18 4.3 构造类型编码 18 4.3.1 序列值的编码 18 4.3.2 集合值的编码 19 4.3.3 单一序列值的编码 19 4.3.4 单一集合值的编码 20 4.4本章小结 20 第5章 基于ASN.1BER规则的解码实现 21 5.1 布尔值的解码 21 5.2 空值的解码 23 5.3 整数值的解码 24 5.4 枚举值的解码 27 5.5 位串值的解码 27 5.6 八位位串值的解码 29 5.7 实数值的解码 30 5.8 构造类型解码 32 5.8.1 序列值的解码 32 5.8.2 单一序列值的解码 35 5.8.3 集合值的解码 35 5.8.4 单一集合的解码 35 5.9 解码系统设计流程图 37 5.10本章小结 38 第6章 基于ASN.1 BER规约的可视化编解码系统及通信 39 6.1 ASN.1BER可视化编解码系统 39 6.2编解码系统通信的实现 40 6.3编解码系统的测试 41 6.4本章小结 43 第7章 总结 44 7.1主要内容回顾 44 7.2本次设计的不足和进一步完善 44 致谢 46 参考文献 47 附录A 外文翻译-原文部分 48 附录B 外文翻译-中文译文 56
评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luming.02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值