Protobuf打包重复字段编码疑问:自算结果与官方示例不符
问题解析与修正
核心错误:看错了官方示例的字段值
你把官方Test4示例里重复字段e的取值搞错了——官方用的是[3, 270, 86942],不是你以为的[1,2,3],这是编码结果对不上的最主要原因。
计算Tag时的逻辑错误
你写的(100 << 3 | 10)或(110<<3 | 10)完全不符合Protobuf的Tag规则:
- Tag的计算是「字段编号左移3位」按位或「Wire Type」,其中Wire Type是3位二进制值(只能取0-5),不是十进制数。
- 字符串类型和打包重复字段对应的Wire Type是2(长度前缀类型):
- 字段
d(编号4)的正确Tag计算:(4 << 3) | 2 = 34(十六进制0x22),你结果蒙对了,但逻辑错了。 - 字段
e(编号6)的正确Tag计算:(6 << 3) | 2 = 50(十六进制0x32),结果对但逻辑错误。
- 字段
官方编码的正确拆解
官方给出的完整编码是32 06 03 8E 02 9E A7 05 22 05 68 65 6C 6C 6F,拆分后:
重复字段e的编码部分(32 06 03 8E 02 9E A7 05)
0x32:Tag,对应字段6、Wire Type 2(打包重复字段)0x06:后续数据的总长度(6字节)0x03:int32值3的varint编码0x8E 0x02:int32值270的varint编码(计算:0x8E | (0x02 << 7) = 142 + 256 = 270)0x9E 0xA7 0x05:int32值86942的varint编码(计算:0x9E | (0xA7 <<7) | (0x05 <<14) = 158 + 16928 + 81920 = 86942)
字符串字段d的编码部分(22 05 68 65 6C 6C 6F)
这部分你的计算是对的:
0x22:Tag,对应字段4、Wire Type 20x05:"hello"的长度(5字节)0x68 0x65 0x6C 0x6C 0x6F:"hello"的UTF-8编码
关于你的自编码逻辑
如果按你假设的e=[1,2,3],正确的打包重复字段编码确实是32 03 01 02 03,加上字符串字段的编码后组合结果是正确的,但这和官方示例无关,因为官方的e取值完全不同。
内容的提问来源于stack exchange,提问作者meteora
相关产品推荐
相关产品推荐

