protobuf中的Base 128 Varints类型分析

简介: protobuf中的Base 128 Varints类型分析

Google Protobuf里面提出了“Base 128 Varints”编码,这是一种变字节长度的编码,官方描述为:varints是用一个或多个字节序列化整形的一种方法。我理解要点有三个(1)操作是序列化(2)操作对象是整形(3)变长编码。重点是最后一点,他是如何编码的呢?

      (1)除了最后一个字节,varint中的每个字节的最高位设为1,表示后面还有字节出现

      (2)每个字节的低7位看成是一个组(group),这个组和他相邻的下一个7位组共同存储某个整形的“组合表示”,最低有效组在前面。

   上面的定义可能比较生硬,我没看具体例子之前,也没搞明白,我们来看https://developers.google.com/protocol-buffers/docs/encoding?hl=en#varints中的例子:

       (1)一个字节。下面只有一个字节,所以最高位是0,表示十进制1

           0000 0001

       (2)两个字节。

           1010 1100 0000 0010

       由于第一个字节后面还有一个字节,所以第一个字节的最高位设置为1,表示后面还有后继字节,第二个字节的最高位为0。去掉每个字节的最高位,我们对两个字节进行分组。第一个7位组:0101100,第二个7位组:0000010,组合起来就是:0101100 0000010,由于最低有效组在前面,所以两个7位组进行调换,结果为:0000010  0101100,中间的空格是为了大家区分,去掉前面的0,也就是:100101100,十进制为1*2^8 + 1*2^5 + 1*2^3 + 1*2^2 = 256 + 32 + 8 + 4 = 300。

      (3)三个字节。我们换种方式,给定某个整形,要求写出他的varint表示,这里当然是落在需要3个字节表示的整形。16380可以吗?不可以!因为16380 < 2^14,所以2个字节足以,我们就以27491为例,27491的二进制表示为:

                    0110 1011 0110 0011

       注意这里是高字节之前,低字节在后,和varint的编码规则相反,首先按照7位一组划分为:0000001 1010110  1100011,然后反转为:1100011 1010110  0000001,最后将末尾的7位组前面补0组成一个字节,两个7位组都补1分别组成一个字节:

                    11100011 11010110  00000001

      (4)更多字节。聪明的你可能发现,varint编码中4个字节最大表示的数为2^28,非常正确,同时说明了天下没有免费的午餐,有得有失。Protobuf引入了fixed32解决这个问题的,如果某个字段经常大于2^28,应当优选fixed32,他是固定长度为32位的。

    三.String和bytes

    string和bytes的表示形式一致,都是“长度+值”,其中长度采用varint编码,值为字符序列或者二进制码流

目录
相关文章
|
7月前
|
编解码 Java 编译器
【Protobuf】Protobuf中的Message语法规范
在Message中定义一个或者多个字段,FieldType是字段的数据类型,可以是基本类型(如int32、string、bool等)或其他定义的Message类型。fieldName是字段的名称,可以根据需求自定义。fieldNumber是字段的唯一标识号,用于在消息的二进制编码中标识字段。
160 0
|
7月前
|
存储 Java
使用Java进行Base64编码的示例
使用Java进行Base64编码的示例
70 1
|
5天前
将图片(路径)转换为Base64 和 将base64转换为file类型
将图片(路径)转换为Base64 和 将base64转换为file类型
|
7月前
|
JSON Go 数据格式
Golang 语言中怎么解码 4 种常见JSON 格式数据?
Golang 语言中怎么解码 4 种常见JSON 格式数据?
33 0
|
5天前
|
存储 XML JSON
protobuf原理以及实例(Varint编码)
protobuf原理以及实例(Varint编码)
46 0
|
5天前
|
存储 Java Go
|
5天前
|
JSON 数据格式
protobuf与json相互转换的方法
protobuf与json相互转换的方法
56 0
|
5月前
|
JSON Go 数据格式
go 变量与json相互转换
go 变量与json相互转换
43 1
|
JSON Go 数据格式
Golang 处理复杂格式JSON数据(多类型混合)
Golang 处理复杂格式JSON数据(多类型混合)
267 0
|
JSON Go 数据格式
Go 结构体与 JSON 之间的转换
本文介绍了 Go 语言里,JSON 与结构体之间的转换。在结构体转 JSON 时,我们可以通过给字段打标签,指定转换后的 key 命名,需要注意的是,如果结构体的字段为非导出字段或字段的 JSON 标签值为 -,在转换 JSON 时,将会被忽略。反之 JSON 解析结构体时也是一样的。
269 1
Go 结构体与 JSON 之间的转换