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

news2024/11/16 23:40:47

本文将详细介绍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 位)或多个字节(对于较大的标签号)。第一个字节的结构如下:

  • 第1-2位:类(Class)

    • 00:通用类(Universal)

    • 01:应用类(Application)

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

    • 11:私有类(Private)

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

    • 0:原始类型(Primitive)

    • 1:构造类型(Constructed)

  • 第4-8位:标签号(Tag Number)

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

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

笔者这里给出图示如下:

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

简单标签号(0-30)

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

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

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

复杂标签号(>= 31)

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

  • 标签号 31:0b1111 1111 0011 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 的情况,直接使用第4-8位。

  • 对于标签号大于等于 31 的情况,使用多个字节表示,第一字节的第4-8位全为 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编码可以用于图像和视频数据的高效传输和存储。




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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1818142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光伏气象站:智能驱动,助力光伏产业绿色发展

TH-FGF9在全球能源结构转型和环境保护的大背景下&#xff0c;分布式光伏发电以其清洁、可再生的特性&#xff0c;逐渐成为了能源领域的新宠。然而&#xff0c;光伏发电的效率受气象条件影响较大&#xff0c;如光照强度、温度、风速等因素都会对光伏电站的发电效率产生直接影响。…

flask实战之模板实现公共导航

基础实现 目标 在Flask中&#xff0c;使用模板继承和块&#xff08;blocks&#xff09;可以方便地提取公共导航菜单&#xff0c;使得您可以在多个页面上重用相同的导航结构。以下是一个基本示例&#xff0c;展示如何创建一个包含公共导航菜单的模板&#xff1a; 创建基础模板…

Python-Socket网络编程简单示例

# TCP 服务端程序 server.py # 导入socket 库 from socket import *# 主机地址为空字符串&#xff0c;表示绑定本机所有网络接口ip地址 # 等待客户端来连接 IP # 端口号 PORT 50000 # 定义一次从socket缓冲区最多读入512个字节数据 BUFLEN 512# 实例化一个socket对象 # 参…

实测完快手的AI视频「可灵」后,我觉得这才是第一个中国版Sora

6月6号&#xff0c;是快手的13周年生日。 在这一天&#xff0c;所有AI圈的人都想不到&#xff0c;快手在13周年之际&#xff0c;没有任何预兆、没有任何宣传&#xff0c;直接发布了他们的AI视频大模型。 可灵。 给我也干了个措手不及。 我当时正在看360的发布会&#xff0c;…

SD5510 单节锂离子电池充电器和恒定5V升压控制器芯片IC

一般描述 SD5510为一款移动电源专用的单节锂离子电池充电器和恒定5V升压控制器&#xff0c;充电部分集高 精度电压和充电电流调节器、预充、充电状态指示和充电截止等功能于一体&#xff0c;可以输出最大1A充电电流。而升压电路采用CMOS工艺制造的空载电流极低的VFM开关…

SpringBoot不用写Controller、不用写Service、不用建表,直接起飞是什么感觉

Spring Data REST 提供了一种简单的方式来暴露 JPA 实体为 RESTful 服务&#xff0c;这使得构建基于 REST 的数据服务变得非常快速和高效。下面是一个使用 Spring Data REST 构建通用架构的基本示例&#xff1a; 首先&#xff0c;我们需要创建一个实体类&#xff08;例如&…

Centos离线安装Python3

目录 1.准备工作 2.解压python压缩包 3.编译 4.安装、更改环境变量 5.建立pip连接 使用的是Centos7服务器&#xff0c;Py版本是py3.9.0 1.准备工作 首先确保服务器中存在相关的编译器&#xff0c;例如GCC&#xff1b;这里不做过多叙述&#xff0c;需要者前往&#xff1a…

【全开源】旅行吧旅游门票预订系统源码(FastAdmin+ThinkPHP+Uniapp)

&#x1f30d;旅游门票预订系统&#xff1a;畅游世界&#xff0c;一键预订 一款基于FastAdminThinkPHPUniapp开发的旅游门票预订系统&#xff0c;支持景点门票、导游产品便捷预订、美食打卡、景点分享、旅游笔记分享等综合系统&#xff0c;提供前后台无加密源码&#xff0c;支…

milvus的GPU索引

前言 milvus支持多种GPU索引类型&#xff0c;它能加速查询的性能和效率&#xff0c;特别是在高吞吐量&#xff0c;低延迟和高召回率的场景。本文我们将介绍milvus支持的各种GPU索引类型以及它们适用的场景、性能特点。 下图展示了milvus的几种索引的查询性能对比&#xff0c;…

40. 【Java教程】数据库编程

本小节我们将学习如何使用 Java 语言结合数据库进行编程。注意&#xff0c;学习本小节需要你有一定的 SQL 基础&#xff0c;了解 MySQL 数据库的 基础 CRUD 操作。 本小节我们将选择开源免费的 MySQL 5.7 作为数据库&#xff0c;可以去官网下载并安装 MySQL。 通过本小节的学…

nosql数据库的特点

NoSQL简介 NoSQL是一种不同于关系数据库的数据库管理系统设计方式,是对非关系型数据库的统称,它所采用的数据模型并非传统关系数据库的关系模型,而是类似键/值、列族、文档等非关系模型。NoSQL数据库没有固定的表结构,通常也不存在连接操作,也没有严格遵守ACID约束。因此…

无法在地址[localhost]和端口[8005]上创建服务器关闭套接字(基本端口[8005]和偏移量[0])

今天小伙伴问我一个问题&#xff0c;说是新服务器启动应用&#xff0c;报了一个错误&#xff0c;如下&#xff1a; 一开始我怀疑是端口被占用 经过排查端口没有被占用&#xff0c;然后我怀疑localhost解析有问题 经过 ping localhost 后&#xff0c;得到以下结果到这里很明…

SpringBoot集成slf4j日志配置

目录 前言 1、slf4j概述 2、pom.xml的日志依赖 3、application.yml的日志配置 4、logback.xml配置文件定义 5、logback.xml配置文件解析 5.1 定义日志的存储路径 5.2 定义日志的输出格式 5.3 定义控制台输出 5.4 定义日志相关参数 5.5 定义日志的输出级别 6、测试日…

mysql中 redo日志(下)

大家好。上篇文章我们介绍了什么是redo日志以及redo日志的写入过程。建议没看过上篇文章的同学先看一下上一篇文章&#xff0c;今天我们继续来说一说redo日志。 一、redo日志文件 1. redo日志刷盘时机 我们知道mtr运行过程中产生的一组redo日志在mtr结束时会被复制到log buf…

利用AI大模型,将任何文本语料转化为知识图谱,可本地运行!

几个月前&#xff0c;基于知识的问答&#xff08;KBQA&#xff09;还是一个新奇事物。 现在&#xff0c;对于任何 AI 爱好者来说&#xff0c;带检索增强生成&#xff08;RAG&#xff09;的 KBQA 就像小菜一碟。看到自然语言处理&#xff08;NLP&#xff09;的可能性领域由于大…

JVM性能优化案例:优化垃圾回收器的年轻代和老年代占比

JVM性能优化案例&#xff1a;优化垃圾回收器的年轻代和老年代占比 我们有一款在线交易系统&#xff0c;要求低延迟和高吞吐量。系统运行在Ubuntu服务器上&#xff0c;使用OpenJDK 11&#xff0c;并启用了G1垃圾回收器。以下是系统的基本配置和GC日志信息&#xff1a; 操作系统…

学习笔记丨嵌入式BI分析的12个关键功能

编者注&#xff1a;以下内容节选编译自嵌入式分析厂商Qrvey发表的《What is Embedded Analytics?》&#xff08;什么是嵌入式分析&#xff09;一文&#xff0c;作者为Qrvey产品市场主管Brian Dreyer。 什么是嵌入式分析&#xff1f; 嵌入式分析是指能够将数据分析的特性和功…

React+TS前台项目实战(七)-- 全局常用组件Select封装

文章目录 前言Select组件1. 功能分析2. 代码详细注释说明3. 使用方式4. 效果展示&#xff08;1&#xff09;鼠标移入效果&#xff08;2&#xff09;下拉框打开效果&#xff08;3&#xff09;回调输出 总结 前言 今天这篇主要讲全局select组件封装&#xff0c;可根据UI设计师要…

java1.8运行arthas-boot.jar运行报错解决

报错内容 输入java -jar arthas-boot.jar&#xff0c;后报错。 [INFO] JAVA_HOME: D:\developing\jdk\jre1.8 [INFO] arthas-boot version: 3.7.2 [INFO] Can not find java process. Try to run jps command lists the instrumented Java HotSpot VMs on the target system.…

资源付费系统小程序APP公众号h5源码

&#x1f510; 揭秘“资源付费系统”&#xff1a;知识、技能与价值的交汇点 &#x1f48e; &#x1f31f; 引言&#xff1a;为何资源需要付费&#xff1f; 在数字化时代&#xff0c;我们周围充斥着大量的信息。但并非所有信息都具有同等的价值。其中&#xff0c;那些经过精心…