Protobuf校验和(CRC)

Sin*_*atr 6 crc protocol-buffers

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

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

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

我可以将protobuf流放入包装器中,但是再次打开/包装仍然是开销。

是否有一种简单便宜的方法可以在protobuf流的末尾添加某些内容,从而避免反序列化期间需要进行其他操作?在XML中,我可以添加注释。我认为protobuf中没有注释,但是如何以1或2字节的CRC为例呢?

Mar*_*ell 6

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

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

然而!这样做的麻烦之处在于,解码器仍将经常解释和存储此数据,这意味着如果您对其进行序列化,它将在输出中包含此数据。

避免这种情况的另一种方法是将protobuf数据封装在您自己设计的某种成帧机制中。例如,您可以选择执行以下操作:

  • 4个字节代表原生缓冲区有效载荷长度“ n”
  • 原生缓冲区有效载荷的“ n”个字节
  • 在“ n”个字节上计算出2个字节的CRC数据

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