【问题标题】:Protobuf checksum (crc)Protobuf 校验和 (crc)
【发布时间】:2014-05-11 23:43:58
【问题描述】:

我打算将一些大对象存储到数据库 (BLOB) 中。在我看来,protobuf 是序列化/反序列化 BLOB 的最佳候选者之一。尽管它具有二进制格式,但它仍然易于阅读和更改其内容(字符串、整数等)。所以我需要某种数据验证,无论何时原始 BLOB 或修改(被黑客?被太聪明的用户?)。

一种可能性是在表中有一个专用字段,称为crc,计算 BLOB 的校验和并将其放在那里。但是当 crc 是 BLOB 本身的一部分时(在许多情况下)会好得多。

我可以在 protobuf 流的末尾添加 额外 个字节,但我必须删除它们(否则反序列化器会抛出异常“invalid field blablabla”)。

我可以将 protobuf 流放入包装器中,但解包/包装又是开销。

是否有一种简单且便宜的方法可以在 protobuf 流的末尾添加一些内容,以避免在反序列化期间需要额外的操作?在 XML 中,我可以添加注释。我认为 protobuf 中没有注释,但是如何将 1 或 2 个字节的 CRC 放在示例中?

【问题讨论】:

    标签: protocol-buffers crc


    【解决方案1】:

    Crc 应该保存在之前。这使得通过使用Seek(跳过标题)从流中反序列化变得微不足道。

    这是最简单的实现:

    // serialize
    using (var file = File.Create("test.bin"))
    using (var mem = new MemoryStream())
    {
        Serializer.Serialize(mem, obj); // serialize obj into memory first
        // ... calculate crc
        file.Write(new byte[] { crc }, 0, 1);
        mem.WriteTo(file);
    }
    
    // deserialize
    using (var file = File.OpenRead("test.bin"))
    {
        var crc = file.ReadByte();
        // ... calculate and check crc
        file.Seek(1, SeekOrigin.Begin);
        Serializer.Deserialize<ObjType>(file);
    }
    

    【讨论】:

      【解决方案2】:

      Protobuf 流是可附加的。如果您知道数据中不存在的字段编号,您可以简单地将数据附加到该字段。如果您打算添加 1 或 2 个字节的 CRC 数据,那么“varint”可能是您最好的选择(请注意,“varint”是 7 位编码格式,第 8 位是延续标记,因此您可能想要使用7、14 或 21 位或实际的 CRC 数据),那么您可以追加:

      • 选择的字段编号,左移 3 位,然后 varint 编码
      • CRC 数据,varint 编码

      但是!问题在于解码器仍会经常解释和存储这些数据,这意味着如果您对其进行序列化,它会将这些数据包含在输出中。

      避免这种情况的另一种方法是将 protobuf 数据封装到您自己设计的某种框架机制中。例如,您可以选择这样做:

      • 4字节表示protobuf有效载荷长度,“n”
      • “n”字节的 protobuf 负载
      • 在“n”个字节上计算出的 2 个字节的 CRC 数据

      我可能会选择第二个选项。请注意,如果需要,您可以为长度前缀选择“varint”编码而不是固定长度编码。不过,对于 CRC 来说可能不值得,因为 是固定长度的。

      【讨论】:

      • 好的,那我就用header了。作为奖励,这将允许我进行版本控制,以防 protobuf 不能(例如,如果我决定突然创建一个基类,protobuf 将 not work with old i> 继承数据,只是对其进行了测试,例如,在XmlSerializer 中,继承某些东西不是问题)
      猜你喜欢
      • 2015-06-29
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      • 2013-12-21
      • 2021-05-11
      • 2013-01-10
      • 2022-01-12
      • 1970-01-01
      相关资源
      最近更新 更多