Ubuntu下使用Protocol Buffer(简写:protobuf) (1.2编码)
1.2protobuf编码规则
1.2.1先了解varints编码
以300为例:1010 1100 0000 0010,这串数字是怎么来的呢?
1.首先删除每个字节的msb位,得到每7位为一组的数字:
1010 1100 0000 0010
010 1100 000 0010
2.反转两组7位,再相连++
010 1100 000 0010
000 0010 ++ 010 1100 (反转两组7位,再相连++)
100101100 (300的二进制码)
-> 256+32+8+4=300
一个protobuf message是一系列的key-value对,key可以看成一个Tag。当对消息进行编码时,key和value被串联到一个字节流中。对message进行解码时,解析器需要能够跳过无法识别的字段。
Key (Tag) |
Value |
在流message中每一个key都是varint编码的值,格式:(field_number<<3)|wire_type
。数字的最后3bit存储the wire type,
Tag编码格式
编码结构图
每个field具有两种格式:
1.Tag-Length-Value :对应Type 2类型 Length-delimited
2. Tag-Value : 对应Type 1类型 int32, int64, uint32
编码与解码过程
例1:
在message中
int32 val =666;
原码:101 0011010
补码:101 0011010 (正数的补码=原码,负数的补码= 原码按位取反,再+1)
编码过程:
对补码101 0011010 从后向前取7位一组,并反转排序,得:
0011010 0000101
在加上msb,得
1 0011010 0 0000101(0x9a 0x05)
解码过程:先得到编码的结果为1 0011010 0 0000101(0x9a 0x05)
这里的第一个字节 msb = 1,所以需要再读一个字节,第二个字节的 msb = 0,则读取两个字节后停止。读到两个字节后先去掉两个 msb,剩下:
0011010 0000101
将这两个7-bit组反转得到补码:
0000101 0011010
将补码还原成原码,得:
666
例2:08(以去除msb位)
000 1000
例如:
96 01 = 1001 0110 0000 0001
→ 000 0001++ 001 0110 (先去掉msb位,再反转7位,在相连)
→ 10010110
→ 128+16+4+2=150