BER是basic encoding rules的简称,它是一种简单的编码规则。
BER的优点:提供了一套规则,使得任何按该规则编码的一段数据(八位组流)都能够按照此规则被解析,这种规则使得一段数据自包含自身的结构信息。
BER的传输格式一直是TLV三元组:可以解释为<Type, Length, Value> ;亦可解释为<Tag, Length, Value>。见下图:
TLV每个域都是一系列八位组,对于组合结构,其中V还可以是TLV三元组,因而形成嵌套结构(如下图)。BER采取大端编码c.1,其八位组的高位比特在左手边。
BER编码中的Tag(通常是一个八位组),指明了值的类型,其中一个比特表征是基本类型还是组合类型。Tag有如下两种形式:
当Tag不大于30时,Tag只在一个八位组中编码;当Tag大于30时,则Tag在多个八位组中编码。在多个八位组中编码时,第一个八位组后五位全部为1,其余的八位组最高位为1表示后续还有,为0表示Tag结束。Tag的值需要将上图中黄色部分拼接后才能得到。
BER编码中Length表示Value部分所占八位组的个数,有两大类:定长方式(Definite Form)和不定长方式(Indefinite Form);在确定方式中,按照Length所占的八位组个数又分为短、长两种形式。具体如下:
采用定长方式,当长度不大于127个八位组时,Length只在一个八位组中编码;当长度大于127时,在多个八位组中编码,此时第一个八位组低七位表示的是Length所占的长度,后续八位组表示Value的长度。
采用不定长方式时,Length所在八位组固定编码为0x80,但在Value编码结束后以两个0x00结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息给对方。
注释:
c.1 大端模式(big endian)和小端模式(little endian)是计算机中数据存储模式。由于芯片厂商众多,所以存在不同的存储模式。典型的,intel体系采用小端模式,低字节存储在低地址,如int 1的存储模式为 0x01 0x00 0x00 0x00(假设内存地址向后增长),大端模式则与之相反。同样对一个字节,也存在大端与小端之说,如果高位比特存在于字节左手边,则为大端模式,否则为小端模式。欲验证你机器所采用的模式,可以通过写一个小的c程序测试一下。关于big endian和little endian的起源可以追溯到《格列夫游记》,里面描叙了小人国的战争因为人们敲鸡蛋位置的不同而起。喜欢从圆头敲鸡蛋的人被归为big endian,喜欢从尖头敲鸡蛋的人被归为little endian。哈哈,有意思吧。不过,真正的理解大小端模式的区别,必须要从系统的角度,从指令集,寄存器和数据总线上深入理解。
从软件的角度考虑,一个对端模式比较在意的应用是网络。由于网络上传输的数据是比特流,也可以说是字节流(因为,对字节而言基本上是大端模式)。网络上的字节流也是采取大端模式的,所以当传输一个整数时,我们必须把本地端模式表示的整数先转为大端模式然后通过接口传送到媒体,在另一端又必须把该字节流还原成对应体系结构的端模式。