protobuf中的编码规则

简介: protobuf中的编码规则 (1)序列化和反序列化: 在开始本部分的内容之前,首先有必要介绍两个基本概念,一个是序列化,一个是反序列化。这两个概念的定义在网上搜一下都很多的,但大多都讲得比较晦涩,不太好理解,在这里我会用比较通俗的文字来解释,尽可能让读都朋友们一读就明白是怎么回事: 序列化:是指将结构化的数据按一定的编码规范转成指定格式的过程; 反序列化:是指将转成指定格式的数据解析成原始的结构化数据的过程。

protobuf中的编码规则

(1)序列化和反序列化

在开始本部分的内容之前,首先有必要介绍两个基本概念,一个是序列化,一个是反序列化。这两个概念的定义在网上搜一下都很多的,但大多都讲得比较晦涩,不太好理解,在这里我会用比较通俗的文字来解释,尽可能让读都朋友们一读就明白是怎么回事

序列化是指将结构化的数据按一定的编码规范转成指定格式的过程

反序列化是指将转成指定格式的数据解析成原始的结构化数据的过程

举个例子,Person是一个表示人的对象类型,person是一个Person类型的对象,将person存到一个对应的XML文档中的过程就是一种序列化,而解析XML生成对应Person类型对象person的过程,就是一个反序列化的过程。在这里结构化数据指的就是Person类型的数据,一定的编码规范指的就是XML文档的规范。XML是一种简单的序列化方式,用XML序列化的好处是,XML的通用性比较好,另外,XML是一种文本格式,对人阅读比较友好,但是XML方式比较占空间,效率也不是很高。通常,比较高效的序列化都是采用二进制方式的,将要序列化的结构化数据,按一定的编码规范,转成为一串二进制的字节流存储下来,需要用的时候再从这串二进制的字节流中反序列化出对应的结构化的数据。

通过上面的介绍,我们给protobuf下一个比较正式的定义了Google ProtoBufGoogle制定的一种用来序列化结构化数据的程序库。

(2ProtoBuf中的编码

1) ProtoBuf编码基础——Varints, varints是一种将一个整数序列化为一个或者多个Bytes的方法,越小的整数,使用的Bytes越少。

Varints的基本规则是

(a)每个Byte的最高位(msb)是标志位,如果该位为1,表示该Byte后面还有其它Byte,如果该位为0,表示该Byte是最后一个Byte

(b)每个Byte的低7位是用来存数值的位

(cVarints方法用Litte-Endian(小端)字节序

举个例子300Varints序列化的结果是1010 1100 0000 0010,运算过程如下 所示

1010 1100 0000 0010->010 1100 000 0010(去标志位)->

000 0010 010 1100(调整字节序)-> 1 0010 1100 ->256+32+8+4=300(计算值)

2)ProtoBuf中消息的编码规则

(a)每条消息(message)都是有一系列的key-value对组成的 keyvalue分别采用不同的编码方式。

(b)对某一条件消息(message)进行编码的时候,是把该消息中所有的key-value对序列化成二进制字节流;而解码的时候,解码程序读入二进制的字节流,解析出每一个key-value对,如果解码过程中遇到识别不出来的类型,直接跳过。这样的机制,保证了即使该消息添加了新的字段,也不会影响旧的编/解码程序正常工作。

(ckey由两部分组成,一部分是在定义消息时对字段的编号(field_num),另一部分是字段类型(wire_type)。字段类型定义如下表所示。

Type

Meaning

Used For

0

Varint

int32, int64, uint32, uint64, sint32, sint64, bool, enum

1

64-bit

fixed64, sfixed64, double

2

Length-delimited

string, bytes, embedded messages, packed repeated fields

3

Start group

groups (deprecated)

4

End group

groups (deprecated)

5

32-bit

fixed32, sfixed32, float

(dkey的编码方式field_num << 3 | wire_type

(evarint类型(wire_type=0)的编码,与第(1)部分中介绍的方法基本一致,但是int32, int64sint32,sint64有些特别之处int32int64就是简单的按varints方法来编码,所以像-1-2这样负数也会占比较多的Bytes。于是sint32sint64采用了一种改进的方法先采用Zigzag方法将所有的整数(正数、0和负数)一一映射到所有的无符号数上,然后再采用varints编码方法进行编码。Zigzag映射函数为

Zigzag(n) = (n << 1) ^ (n >> 31),  nsint32

Zigzag(n) = (n << 1) ^ (n >> 63),  nsint64

下表是一个比较直观的映射表,这样映射后再进行编码的好处就是绝对值比较小的负数序列化后的结果占的Bytes数也会比较少。

Signed Original

Encoded As

0

0

-1

1

1

2

-2

3

2

4

-3

5

2147483647

4294967294

-2147483648

4294967295

(f64-bit(wire_type=1)32-bit(wire_type=5)的编码方式就比较简单了,直接在key后面跟上64bits32bits,采用Little-Endian(小端)字节序。

(glength-delimited(wire_type=2)的编码方式key+length+content, key的编码方式是统一的,length采用varints编码方式,content就是由length指定的长度的Bytes

(hwire_type=34的现在已经不推荐使用了,因此这里也不再做介绍。

3ProtoBuf编解码中字段顺序(Field order)的问题

(a) 编码/解码与字段顺序无关,这一点由key-value机制就能保证

(b)对于未知的字段,编码的时候会把它写在序列化完的已知字段后面。

原文

http://www.wuzesheng.com/?p=1258

目录
相关文章
|
8天前
|
文件存储
Unicode标准与其他编码规则
Unicode标准与其他编码规则
23 0
|
4月前
|
XML JSON 安全
Base64编码原理与在网络传输中的应用
Base64编码原理与在网络传输中的应用
|
6月前
再见手动编码,标准自动化编码规则来帮忙!
标准管理员小S面临数据标准编码管理的挑战:编码格式不统一、编码值不可读活相关性差,手动管理耗时易出错。Dataphin新推出“标准编码规则”功能,可以实现一次配置批量生成编码,并通过自增序列、固定字符串和所属标准集编码的组合,保证编码相关性和灵活性,同时提供了编码规则变更后的批量订正功能,大大简化管理工作。小S对此表示高度满意。
141 0
|
6月前
|
存储 XML JSON
protobuf原理以及实例(Varint编码)
protobuf原理以及实例(Varint编码)
147 0
|
XML 存储 JSON
数据序列化工具 Protobuf 编码&避坑指南
我们现在所有的协议、配置、数据库的表达都是以 protobuf 来进行承载的,所以我想深入总结一下 protobuf 这个协议,以免踩坑。 先简单介绍一下 Protocol Buffers(protobuf),它是 Google 开发的一种数据序列化协议(与 XML、JSON 类似)。它具有很多优点,但也有一些需要注意的缺点: 优点: 效率高:Protobuf 以二进制格式存储数据,比如 XML 和 JSON 等文本格式更紧凑,也更快。序列化和反序列化的速度也很快。 跨语言支持:Protobuf 支持多种编程语言,包括 C++、Java、Python 等。 清晰的结构定义:使用 prot
|
JSON 前端开发 数据格式
crontab、JSON、前端、后端、通信、转换、编码、解码、表达式工具
crontab、JSON、前端、后端、通信、转换、编码、解码、表达式工具
132 0
crontab、JSON、前端、后端、通信、转换、编码、解码、表达式工具
AVI格式视频文件编码格式缺少编码解释器且该项目的编码格式不受支持(0xc00d5212错误)
AVI格式视频文件编码格式缺少编码解释器且该项目的编码格式不受支持(0xc00d5212错误)
3094 0
AVI格式视频文件编码格式缺少编码解释器且该项目的编码格式不受支持(0xc00d5212错误)
|
编解码 JavaScript 前端开发
字符串base64编解码的多种语言实现
字符串base64编解码的多种语言实现
字符串base64编解码的多种语言实现
|
算法 区块链 索引
【密码学】Base64 编码 ( Base64 简介 | Base64 编码原理 | 最后编码组字节不足时补位 ‘=‘ 符号 | Base64 编码实现参考 )(一)
【密码学】Base64 编码 ( Base64 简介 | Base64 编码原理 | 最后编码组字节不足时补位 ‘=‘ 符号 | Base64 编码实现参考 )(一)
435 0
【密码学】Base64 编码 ( Base64 简介 | Base64 编码原理 | 最后编码组字节不足时补位 ‘=‘ 符号 | Base64 编码实现参考 )(一)
|
存储 安全 索引
计算机编码规则之:Base64编码
计算机编码规则之:Base64编码