如果 运行 在不同 languages/architectures 上的相同输入上,protobuf 会生成按位完美副本吗?

Will protobuf generate bitwise perfect copy if ran on the same input on different languages/architectures?

如果我在多台机器(arm、x86、amd64 等)上使用相同的 .proto 文件,使用不同的语言(c++、python、java、等),在这些不同的配置中序列化时,相同的消息会产生完全相同的字节序列吗?

我想使用这些字节进行哈希处理,以确保相同的消息在不同平台上生成时最终会得到完全相同的哈希值。

"Often, but not quite always"

您可能出现差异的原因包括:

  • 它只是一个"should",而不是"must",字段是按数字顺序写入的 - citation, emphasis mine:

    when a message is serialized its known fields should be written sequentially by field number

    并且 要求 字段是这样排序的("must" 反序列化器能够处理乱序的字段);这尤其适用于讨论 unexpected/extension 字段;如果两个序列化选择不同的字段顺序,字节将不同

  • protobuf可以通过合并两个部分消息来构造,这必然会导致乱序字段,但是当重新序列化从合并消息反序列化的对象时,它可能会变得规范化(顺序)
  • "varint" 编码允许一些细微的歧义...数字 1 通常被编码为 0x01,但它可以 被编码作为 0x8100 或 0x818000 或 0x81808080808000 - 规范实际上并不要求 (AFAIK) 使用最短的版本;不过,我不知道有任何实际输出这种次正规形式的实现:)
  • 一些选项被设计为向前和向后兼容;特别是,repeated 原始值上的 [packed=true] 选项可以随时安全地切换,图书馆应该能够处理它;如果您最初以一种方式序列化它,而现在您使用另一种方式序列化它:结果可能不同;这样做的一个副作用是特定的库也可以简单地 选择 来使用替代表示,特别是如果它知道它会更小;如果两个库在这里做出不同的决定 - 不同的字节

在大多数常见情况下,是的:它将是可靠且可重复的。但这并不是真正的保证。

字节应该兼容,但是-它仍然具有相同的语义-只是字节不同。您使用什么语言、框架、库、运行时或处理器并不重要。如果是这样:那就是一个错误。