gpt4 book ai didi

protocol-buffers - 如何解释 Protocol Buffer 的嵌入式消息二进制有线格式?

转载 作者:行者123 更新时间:2023-12-04 15:44:46 27 4
gpt4 key购买 nike

我试图了解 Protocol Buffer 编码方法,将消息转换为二进制(或十六进制)格式时,我无法理解嵌入消息的编码方式。

我猜可能和内存地址有关,但我找不到准确的关系。

这是我所做的。

第 1 步:我在 test.proto 文件中定义了两条消息,

syntax = "proto3";
package proto_test;

message Education {
string college = 1;
}

message Person {
int32 age = 1;
string name = 2;
Education edu = 3;
}

第 2 步:然后我生成了一些 go 代码,

protoc --go_out=. test.proto

第 3 步:然后我检查消息的编码格式,

p := proto_test.Person{
Age: 666,
Name: "Tom",
Edu: &proto_test.Education{
College: "SOMEWHERE",
},
}
var b []byte
out, err := p.XXX_Marshal(b, true)
if err != nil {
log.Fatalln("fail to marshal with error: ", err)
}
fmt.Printf("hexadecimal format:% x \n", out)
fmt.Printf("binary format:% b \n", out)

哪些输出,

hexadecimal format:08 9a 05 12 03 54 6f 6d 1a fd 96 d1 08 0a 09 53 4f 4d 45 57 48 45 52 45 
binary format:[ 1000 10011010 101 10010 11 1010100 1101111 1101101 11010 11111101 10010110 11010001 1000 1010 1001 1010011 1001111 1001101 1000101 1010111 1001000 1000101 1010010 1000101]

我的理解是,

08                         - int32 wire type with tag number 1
9a 05 - Varints for 666
12 - string wire type with tag number 2
03 - length delimited which is 3 byte
54 6f 6d - ascii for "TOM"
1a - embedded message wire type with tag number 3
fd 96 d1 08 - ? (here is what I don't understand)
0a - string wire type with tag number 1
09 - length delimited which is 9 byte
53 4f 4d 45 57 48 45 52 45 - ascii for "SOMEWHERE"

fd 96 d1 08 代表什么?好像d1 08一直都在,但是fd 96有时会变,不知道为什么。感谢您的回答:)


添加

我调试了 marshal 进程并报告了一个错误 here .

最佳答案

在那个位置我/你会期望嵌入消息中的字节数。

我已经用 Python 重复了你的实验。

msg = Person()
msg.age = 666
msg.name = "Tom"
msg.edu.college = "SOMEWHERE"

我得到了不同的结果,这是我所期望的。声明嵌入消息大小的 varint。

0x08
0x9A, 0x05
0x12
0x03
0x54 0x6F 0x6D
0x1A
0x0B <- Equals to 11 decimal.
0x0A
0x09
0x53 0x4F 0x4D 0x45 0x57 0x48 0x45 0x52 0x45

接下来我反序列化了你的字节:

msg2 = Person()
str = bytearray(b'\x08\x9a\x05\x12\x03\x54\x6f\x6d\x1a\xfd\x96\xd1\x08\x0a\x09\x53\x4f\x4d\x45\x57\x48\x45\x52\x45')
msg2.ParseFromString(str)
print(msg2)

这样的结果是完美的:

age: 666
name: "Tom"
edu {
college: "SOMEWHERE"
}

我得出的结论是,Protobuf 中有一些不同的编码方式。我不知道在这种情况下做了什么,但我知道负 32 位 varint 的例子。正 varint 以五个字节编码,负值转换为 64 位值并编码为十个字节。

关于protocol-buffers - 如何解释 Protocol Buffer 的嵌入式消息二进制有线格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56379536/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com