java协议缓冲区,序列化数据中有什么?

wz8daaqr  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(314)

我是新的协议缓冲区,并真的想知道更多关于它,所以对不起noob的问题。
序列化数据中有什么,只有值还是同时包含键和值?我认为只有价值观,如果有人想反序列化它,他/她必须有计划。

ttcibm8c

ttcibm8c1#

它既是关键又是价值:
如您所知,协议缓冲区消息是一系列的键值对。消息的二进制版本只使用字段的编号作为键—每个字段的名称和声明的类型只能在解码端通过引用消息类型的定义(即.proto文件)来确定。https://developers.google.com/protocol-buffers/docs/encoding
例如,假设您有一个proto文件:

$  cat my.proto 
message header {
  required uint32 u1 = 1;
  required uint32 u2 = 2;
  optional uint32 u3 = 3 [default=0];
  optional bool   b1 = 4 [default=true];
  optional string s1 = 5;
  optional uint32 u4 = 6;
  optional uint32 u5 = 7;
  optional string s2 = 9;
  optional string s3   = 10; 
  optional uint32 u6 = 8;
}

从内存转储编码数据:

(gdb) x/10xb 0x7fd70db7e964
0x7fd70db7e964: 0x08    0xff    0xff    0x01    0x10    0x08    0x40    0xf7
0x7fd70db7e96c: 0xd4    0x38

解码:

$ echo 08ffff01100840f7d438 | xxd -r -p | protoc --decode_raw
1: 32767
2: 8
8: 928375

1、2、8是钥匙
从上面的proto文件:

1 => u1, 
2 => u2,
8 => u6

因此,它变成:

u1: 32767
u2: 8
u6: 928375

我在这里使用了我问题中的数据:

dfty9e19

dfty9e192#

这在一定程度上取决于您使用的是二进制格式(这通常是处理protobuf时的默认格式)还是json格式(是的,protobuf包含一个json选项,至少在某些库中是这样,而不是在所有库中)。
在二进制形式中,数据由字段号和值组成;不是字段名。例如,如果我们使用以下示例:

optional string name = 1; // remove the "optional" if using proto3 syntax

赋值为“nika”(并序列化),则二进制数据将包含 1 (以稍微调整的形式),以及 Nika ,但不包含“name”。
你不一定要有模式来解码它,但是如果你这样做的话,事情会变得容易得多,因为规范的许多部分在其他方面是不明确的,对多个数据类型使用相同的“wire type”(即编码格式),或者对于同一数据类型的多个含义(例如:如果没有模式(或者很好的猜测),您无法判断整数是有符号的、无符号的还是“zig-zag编码的”),并且您得到的实际值可能会有很大的差异。
要查看在没有架构的情况下可以从原始protobuf数据中获得什么,请尝试:https://protogen.marcgravell.com/decode

相关问题