校验和: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-n 和 n 位之间的错误检测性能将非常接近,因此选择更快的那个。那很可能是 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 还是哈希?的主要内容,如果未能解决你的问题,请参考以下文章