protobuf笔记

官网:

https://developers.google.com/protocol-buffers/docs/proto3

https://developers.google.com/protocol-buffers/docs/encoding

编译安装

wget https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.17.3.tar.gz
cd protobuf-3.17.3
sh ./autogen.sh
./coufigure –prefix=/usr/local/protobuf-3.17.3
make -j4
sudo make install

标量值类型(Scalar Value Types)

wire type

 消息存储格式

protobuf采用TLV格式

  1. Tag 作为该字段的唯一标识
  2. Length 代表 Value 数据域的长度
  3. Value 便是数据本身

只有wire type=2(string等类型)的时候才有length字段

TAG和LENGTH使用Base 128 Varints编码

Varints 用来序列化整型,数字(正数)越小占用的字节数越小,例如1int表示是4个字节,而用Varints只要1个字节。

Base 128 Varints编码

每个字节都是variant,每个字节最高位是最高有效位(most significant bit (msb)

msb为1表示还设有下一个字节,为0表示最后一个字节

每个字节后7位表示7位二进制补码

least significant group first个人理解就是小端序,低位字节在低地址,高位字节在高地址。

1的varint编码是:0000 0001

150的varint编码是:1010 1100 0000 0010

150的二进制是1001 0110,由于超过了7位,故要用两个字节表示

下面以消息Test1为例子

message Test1 {
  optional int32 a = 1;
optional string b = 2;
}

int32类型的编码:TAG+VALUE

TAG由两部分组成:field_number+wire_type

field_number即message里等号后面的数字

wire_type共有六种,如上图,故用3位表示即可

所以int32 a = 1;的tag(protobuf中叫做key)值是08

所以假如Test1中a的值是150则编码后的字节流是08 96 01,TAG+VALUE。

string类型的编码

TAG+LENGTH+VALUE

假如Test1中b的值是”ABCD”

则编码后的字节流:

0A 04 41 42 43 44

UTF-8编码

protobuf的字符串用的是UTF8编码,所以下面介绍一下

UTF-88-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码由14个字节组成,常用汉字一般是3个字节,可能4个字节。ASCII字母继续使用1字节存储,重音文字希腊字母西里尔字母等使用2字节来存储,而常用的汉字就要使用3字节。辅助平面字符则使用4字节。

 

 UTF8编码使用了哈夫曼编码中的一点:一个字符序列不会包含在另一个字符的字节序列中。

第一个字节有多少个1,那么这个字符就有多少个字节

以e4bb8a为例:

 

汉字Unicode编码表:http://www.chi2ko.com/tool/CJK.htm

16进制编码转换:http://ctf.ssleye.com/hex.html

 

更多:

int32编码负数字节占用太多

sint32sint64使用ZIGZAG编码负数

enumint32一样都是wire type 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值