protobuf序列化原理

本文详细介绍了protobuf的序列化原理,包括varints编码、Message结构、更多数据类型的编码(如Signed Integers、Strings、Embedded Messages)以及Optional和Repeated Elements的处理。重点阐述了varints如何高效地存储整数,以及在处理有符号整数和字符串时的特殊编码方式。
摘要由CSDN通过智能技术生成

varints

在了解protobuf编码原理之前,首先要了解的是varints
varints是一种用一个或多个字节来序列化整数的方法。整数的值越小,占用的字节数就越少。

varints的每个字节的第一个bit最高有效位(msb)是用来指示下一个字节是不是还是用来表示这个整数的。可以将它看成一个单链表的next指针,为1则指向下一个节点,为0则指向null。而varints较低位的7个bit以二进制补码、低字节序(小端)的形式存储整数。

例如:
有以下varints表示的整数:
1010 1100 0000 0010

要解码得到原来的数值,首先要去掉每个字节的msb(msb只是用来告诉这个整数是不是已经到结尾了,计算数值时并没有用),得到了一下没有msb的形式:
010 1100 000 0010

然后,由于varints是低字节序的,因此需要先对字节进行一个反转(reverse)操作,得到:
000 0010 010 1100
→ 100101100
→ 256 + 32 + 8 + 4 = 300


Message

protobuf message是一系列的键值对,message的二进制形式使用字段的tag数值作为key,而其的字段名以及实际的数据类型则只能在解码端根据message的类型定义来决定。

编码message时,key和value被连接成字节流。当解码message的时候,解释器要有能力跳过那些他不能识别的字段,这样子,才能够添加新的字段进message而且不会影响不能识别这些新字段的老程序。

为此,每个字节流上的每个key实际上是由两个值组成的——一个是字段的tag number,另一个是
该字段的 wire type,这是用来提供足够的信息来明确该字段的值得长度的。

下面是可选的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 repeat
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值