protobuf【2】Varints方法编码

protobuf现在用的也越来越广了,出于好奇研究了一下他的编码格式,和大家一起分享
上一篇博客已经介绍了如何安装和使用protobuf

先介绍 数字1 是怎么存的
Person.proto

syntax = "proto2";
package dong;

message Test1 {
    required int32 a = 1;
}

message Test2 {
    required uint32 age = 1;
    required string name = 2;
}

这里写图片描述

这里主要是创建了一个Test1这样一个结构体,里面存的是int32类型
现在就看看1这样一个int32类型 protobuf是如何进行编码的吧
首先科普一下:

TypeMeaningUsed for
0Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages, packed repeated fields
3Start groupgroups (deprecated)
4End groupgroups (deprecated)
532-bitfixed32, sfixed32, float

【08 01 00】
先解释 08:
08 -> 0000 1000
右移3 -> 00001 000 前面的就是 tag 后面就是 type
tag 就是 required int32 a = 1; 中的编号1
type就是上面表格中的Type 用于辨别是什么类型
所以 08 就代表了 tag = 1,type = int32

再解释 01 00
01 00 -> 0000 0000 0000 0001(注意是小端字节序)
先说Varints:
Varints是使用一个或多个字节序列化整数的方法,varint中的每个字节都具有最高有效位(msb)
也就是说最高位如果被置1那么说明还没有结束,直到有一个字节的最高位为0,说明这个数结束了
所以 000 0000 + 0000 0001 的值就是1

再介绍正数和string的编码

这里写图片描述

age 设置为 150
name 设置为 shuai dong
编码后变成了 【08 96 01 12 0a 73 68 5 61 69 20 64 6f 6e 67】

现在我就手动来解码

  1. 第一个字节是Varints键 08 -> 由上面可知代表了 tag = 1 , type = 0
  2. 96 -> 1001 0110 msb位不为0
  3. 01 -> 0000 0001 msb位为0
  4. 解析tag1:
  5. 去掉msb: 001 0110 0000 0001
  6. 还原:0000 0001 + 001 0110 = 1001 0110 = 150 (再一次提示是小端字节序)
  7. 第一个字节是Varints键 12 -> 0001 0010 由上面可知 tag = 2 , type = 2
  8. 0a:代表后面后10个字节
  9. 解析tag2:
  10. 看一下上面的截图吧后面刚好10个字节 对应的字符串是 shuai dong【帅 东】

可见整数1和整数150占不同的字节
Varints是使用一个或多个字节序列化整数的方法。较小的数字占用较少的字节数。

再说一下uint32的负数形式吧

这里写图片描述

可见负数占了10个字节
带符号的int类型(sint32和sint64)和“标准”类型(int32和int64)之间存在重要的区别。如果使用int32或int64作为负数的类型,则生成的varint 始终为十个字节长, 它被有效地视为非常大的无符号整数。
sint的编码格式:

Signed Original编码为
00
-11
12
-23
21474836474294967294
-21474836484294967295

每个值n都使用编码:
sint32(n << 1 )^ (n >> 31 )
sint64(n << 1 )^ (n >> 63 )

Repeated Fields 今天不想写了 如果明天心情好就在写一篇

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值