protobuf编解码

本文详细介绍了protobuf的TLV编码规则,包括tag、length和value的构成,以及wire_type的使用。通过实际例子演示了如何手动解码protobuf字符串,涉及message定义和字段解读。
摘要由CSDN通过智能技术生成
protobuf 的编码规则

protobuf采用了 TLV(tag-length-value) 编码格式对数据进行编码。每个字段都有唯一的 tag 值,它是字段的唯一标识。length 表示 value 数据的长度,length 不是必须的,对于固定长度的 value,是没有 length 的。value 是数据本身的内容。

对于 tag 值,它有 field_number 和 wire_type 两部分组成。field_number 就是在前面的 message 中我们给每个字段的编号,wire_type 表示类型,是固定长度还是变长的。 wire_type 当前有0到5一共6个值,所以用3个 bit 就可以表示这6个值。tag 结构如下图。
在这里插入图片描述

wire_type 值如下表, 其中3和4已经废弃,我们只需要关心剩下的4种。对于 Varint 编码数据,不需要存储字节长度 length。这种情况下,TLV 编码格式退化成 TV 编码。对于64-bit和32-bit也不需要 length,因为type值已经表明了长度是8字节还是4字节。
在这里插入图片描述

手动解码实例

想要解码protobuf 编码的字符串需要先知道定义的数据格式。现有message定义如下:

message TopMessage{
	int messageType
	message  CallStates {
		int type
		int state
	}
}

现在接受到的字符串:0x08 0x04 0x2A 0x04 0x08 0x02 0x10 0x01
0x08 -> 0000 1000 后三位为000即type为0,说明0x08 0x04是一个filed,0x04就是数据值,对应到TopMessage的结构,message type为 04;
Tips: Varint是一种可变长的编码方式,bit的最高位为1时表示后面也是数据的一部分。所以小于128的值都只需要一个bit,数值越大,需要的位数越多。举个例子,假如接受到的是0x08 0x96 0x01:
0x96 -> 1001 0110,最高位是1,说明后面的01也是数据的一部分。01 -> 0000 0001 最高位为0,说明后面没有数据了。数据传输使用的是小端模式,0x96是数据的低位,0x01是数据的高位,把bit的最高位去掉后进行组合 : 000 0001 001 0110 -> 1001 0110 -> 即message type为 150

0x2A -> 0010 1010 后三位为010即type为2,说明2A后面的04表示数据长度,即0x2A 0x04 0x08 0x02 0x10 0x01是一个filed,对应到TopMessage的结构就是CallStates整个;
继续解析
0x08 -> 0000 1000 后三位为000即type为0,说明0x08 0x02是一个filed,对应到CallStates中就是type为02;
0x10 -> 0001 0000 后三位为000即type为0,说明0x10 0x01是一个filed,对应到CallStates中就是state为01;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值