校验和:CRC 还是哈希?

Posted

技术标签:

【中文标题】校验和:CRC 还是哈希?【英文标题】:Checksumming: CRC or hash? 【发布时间】:2013-01-10 06:17:51 【问题描述】:

除了性能和安全考虑之外,假设哈希函数具有完美的雪崩效应,我应该使用它来校验数据块:CRC32 还是被截断为 N 字节的哈希? IE。哪个将有更小的概率错过错误?具体来说:

    CRC32 与 4 字节哈希 CRC32 与 8 字节哈希 CRC64 与 8 字节哈希

数据块将通过网络传输并重复存储在磁盘上。块的大小可以是 1KB 到 1GB。

据我了解,CRC32 可以检测多达 32 位翻转,并且具有 100% 的可靠性,但之后其可靠性接近 1-2^(-32),并且对于某些模式来说更糟。完美的 4 字节散列可靠性始终是 1-2^(-32),所以去算一下。

8 字节哈希应该具有更好的整体可靠性(2^(-64) 有可能错过错误),那么它是否应该优于 CRC32?那么CRC64呢?

我想答案取决于此类操作中可能出现的错误类型。我们是否可能会看到稀疏的 1 位翻转或大量块损坏?此外,鉴于大多数存储和网络硬件都实现了某种 CRC,不应该已经处理意外的位翻转吗?

【问题讨论】:

我想我对“一般哈希”的含义感到困惑。 好的,删除了“general”,我的错。 【参考方案1】:

只有您可以说 1-2-32 是否适合您的应用程序。一个好的散列函数的 CRC-nn 位之间的错误检测性能将非常接近,因此选择更快的那个。那很可能是 CRC-n

更新:

上面的“那很可能是 CRC-n”只是有点可能。如果使用非常高性能的散列函数,则不太可能。特别是,CityHash 似乎与使用 Intel crc32 硬件指令计算的 CRC-32 几乎一样快!我在一个 434 MB 的文件上测试了三个 CityHash 例程和 Intel crc32 指令。 crc32 指令版本(计算 CRC-32C)占用了 24 毫秒的 CPU 时间。 CityHash64 用了 55 毫秒,CityHash128 用了 60 毫秒,CityHashCrc128 用了 50 毫秒。 CityHashCrc128 使用相同的硬件指令,但它不计算 CRC。

为了快速获得 CRC-32C 计算,我不得不在三个单独的缓冲区上使用三个 crc32 指令,以便在单个内核中并行使用三个算术逻辑单元,然后在汇编程序中编写内部循环。 CityHash 非常快。如果您没有 crc32 指令,那么您将很难像 CityHash64 或 CityHash128 一样快速计算 32 位 CRC。

但是请注意,需要为此目的修改 CityHash 函数,或者需要做出任意选择,以便为大型数据流上的 CityHash 值定义一致的含义。原因是这些函数没有设置为接受缓冲数据,即一次为函数提​​供一个块,并期望得到与一次性将整个数据集提供给函数一样的结果。 CityHash 函数需要修改以更新中间状态。

另一种方法,我为快速和肮脏的测试所做的,是使用种子版本的函数,我将使用前一个缓冲区中的 CityHash 作为下一个缓冲区的种子。问题在于结果取决于缓冲区大小。如果你用这种方法为 CityHash 提供不同大小的缓冲区,你会得到不同的哈希值。

四年后的另一个更新

更快的是xxhash family。我现在建议在 CRC 上使用非加密哈希。

【讨论】:

嗯,有一些散列函数,例如 CityHash 或 MurMurHash,每个时钟周期可以对 1K 消息执行几个字节,因此它们很可能击败未加速的 CRC32 计算。它们产生 128 位输出来引导。所以我想知道关于 CRC 是否有任何概念可以使它比一个好的散列更好的校验和。但我想你是对的,都是关于位数的,所以我想我会选择哈希。 不,CRC 没有任何东西可以使它成为更好的校验和,除非您的噪声源可能是少量的位翻转。我不知道是否有任何哈希函数可以保证检测到所有可能的 1 到 n 位翻转,因为 CRC-n 可以保证。 您对 CityHash 的看法是正确的。我很惊讶它的速度有多快。【参考方案2】:

抛开“性能”问题;您可能需要考虑使用其中一种 SHA-2 函数(例如 SHA-256)。

【讨论】:

哇。这真的将性能问题放在一边。 SHA-256 需要 CRC-32 的 100 倍或 CityHash 的 50 倍。而且没有任何理由,因为这不是一个需要加密哈希的应用程序。 好吧,实际上我可能会。可能不完全是 SHA-256,因为我不需要加密强度,但是,鉴于校验和中的位数在这里是最重要的,查看 256 位哈希可能是有意义的。我只是不确定除了 SHA-256 之外还有什么以及它们是否有用。此外,这不是对散列表的短字符串进行散列,而是对通常应超过 1KB 的消息进行校验和。我想这是一个基准测试的问题,看看它可能会引入多少开销。我一定会保留它作为一种选择。 刚刚快速搜索了一下,你找到了:CityHash 256 位版本!必须比 SHA 快一个数量级。

以上是关于校验和:CRC 还是哈希?的主要内容,如果未能解决你的问题,请参考以下文章

CRC和校验和有什么区别?

CRC是校验文件与压缩问题

关于CRC效验

CRC8,CRC16,CRC32校验不可靠的概率有多高

奇偶校验,海明码与crc码

哈希算法的应用