为什么 LevelDB 和 RocksDB 需要使用“掩码 CRC32”?

5
从leveldb或rocksdb的中,我们可以发现有这样一条注释:
static const uint32_t kMaskDelta = 0xa282ead8ul;

// Return a masked representation of crc.
//
// Motivation: it is problematic to compute the CRC of a string that
// contains embedded CRCs.  Therefore we recommend that CRCs stored
// somewhere (e.g., in files) should be masked before being stored.
inline uint32_t Mask(uint32_t crc) {
  // Rotate right by 15 bits and add a constant.
  return ((crc >> 15) | (crc << 17)) + kMaskDelta;
}

那么,这是什么意思?为什么我们需要口罩?

1个回答

0

掩码

“掩码”在注释和一行代码中有解释。它通过将32位CRC向右旋转15位并添加一个常量来进行修改。

为什么我们需要掩码?

“掩码”不是“必需的”,但建议在存储CRC时使CRC变得比标准CRC更复杂。我不知道为什么建议以这种方式“保护”存储的CRC。如果“掩码”过程是固定且已知的,那么我不明白它如何帮助“保护”存储的CRC。我假设该掩码是自定义的,并且对于实际使用者来说是未知的。

计算包含嵌入式CRC的字符串的CRC会出现问题

我不清楚评论的意思。生成可以位于字符串中任何位置以使计算出的 CRC 有效的数据并不困难。通常,CRC 附加到消息末尾,但是它可以通过将 CRC 乘以 (1/(2^(n))) (在适当的 Galois 字段中)向后循环 n 位,使用无进位乘法进行操作,这可以使用诸如 X86 的 pclmulqdq 指令加速(它使用 xmm 寄存器)。例如,假设要在字符串的第 j 位索引处存储一个 32 位 CRC,其中包括数据和 CRC 的 m 位。将第 j 位索引处的 32 位清零,然后使用标准 CRC 计算 CRC,就好像它将附加到第 m 位索引处一样。然后,将 CRC 向后循环 m-j 位并存储在第 j 位索引处。

在字符串中嵌入多个 CRC 将使反向工程变得困难,但我曾经见过一些游戏使用的保存文件有两个 CRC,都嵌入其中,黑客能够反向工程双 CRC 方法。


我不知道引用的评论是什么意思,但我的初步理解是他们指的是一种大型数据字段,它是其他字段的组合,每个字段(或几个字段)都有自己的CRC。因此,通常情况下,当您计算这种东西的CRC时,每个嵌入式字段,带有自己的CRC,将会“0”出,如果你知道我的意思的话。所以也许人们认为组合字段整体上的误差检测会更少。虽然我不确定为什么。 - davidbak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接