Protocol Buffer内嵌消息二进制编码格式解析求助
First, let's recap how Protocol Buffer encodes nested messages correctly:
- For a nested field, the wire type is 2 (Length-delimited). Your
edufield has tag 3, so the field key is calculated as(3 << 3) | 2 = 26(hex0x1a), which matches the value you see in your output. - Right after the field key, Protocol Buffer should write a Varint-encoded length of the entire nested message content.
- Then follows the serialized bytes of the nested message itself.
What's Wrong with fd 96 d1 08?
Your nested Education message's serialized content is:
0a 09 53 4f 4d 45 57 48 45 52 45
Counting these bytes: that's 11 total bytes. The Varint encoding for 11 is simply 0x0b (binary 1011), so the correct sequence after 0x1a should be 0x0b, not the four-byte sequence fd 96 d1 08.
Decoding fd 96 d1 08 as a Varint gives us the value 18107261, which is wildly larger than the actual length of your nested message. This is clearly incorrect behavior.
Why Does This Happen?
Since you mentioned you've debugged the serialization process and filed a bug, this is almost certainly an issue with the Go Protocol Buffer library's XXX_Marshal method when using the true flag (which enables deterministic serialization). XXX_Marshal is an internal method, so unexpected behavior here points to a bug in the library's handling of nested messages during deterministic marshaling.
Correct Expected Encoding
For your Person message, the valid hex encoding should be:
08 9a 05 12 03 54 6f 6d 1a 0b 0a 09 53 4f 4d 45 57 48 45 52 45
Where 0x0b replaces the incorrect fd 96 d1 08 sequence, representing the 11-byte length of the nested Education message.
内容的提问来源于stack exchange,提问作者Qiankun Zhang

