关于protobuf重复varint解码

时间:2019-02-20 08:57:57

标签: protocol-buffers

我使用charles并从其他iOS应用程序收到了protobuf http消息。现在,我想生成相同的http数据包,但输出不相同。 Other App's message

我的protobuf文件:

message TTCreateConversationBody
{
    repeated uint32 imUid1 = 2;
}

我正在使用Objective-c:

    TTCreateConversationBody *body = [TTCreateConversationBody new];

    GPBUInt32Array *arr = [[GPBUInt32Array alloc] initWithCapacity:2];
    [arr addValue:123123];
    [arr addValue:9999999];

    body.imUid1Array = arr;

和我的输出,查尔斯将其解码为以长度分隔的字符串:

my output

这是原始数据,是我的:

8A-26-10-08-01-10-AE-F7-81-80-9F-03-10-D4-E4-82-F0-D2-01
8A-26-10-08-01-12-0C-F9-F6-C3-9D-FA-02-AE-F7-81-80-9F-03

正确的protobuf文件格式是什么?

1 个答案:

答案 0 :(得分:1)

它们实际上都是有效的……是。

这归结为“打包”字段;如果没有“压缩”,则您的两个整数将被编码为

  • [header,varint] [value] [header,varint] [value]
  • [10] [AE-F7-81-80-9F-03] [10] [D4-E4-82-F0-D2-01]

其中-与“打包”一起变成

  • [标题,字符串] [长度] [值] [值]
  • [12] [0C] [F9-F6-C3-9D-FA-02] [AE-F7-81-80-9F-03]

注意:在两次运行中,实际的看起来非常不同...我假设这是偶然的。

To quote from the specification

  

协议缓冲区解析器必须能够解析已打包的重复字段,就好像它们没有打包一样,反之亦然。这允许以向前和向后兼容的方式将[packed = true]添加到现有字段。

因此:序列化程序应该编写布局,该布局由您的数据是否“打包”来定义,但是解码器必须能够以任何一种方式进行处理。一些库在遇到应该“打包”的数据时:确定哪种布局实际上会更短,然后根据此做出最终决定。实际上,这可以近似为“至少有两个项目时使用打包编码”。