重温,2014 年 8 月
Arnaud Bouchez 在最近的评论中提示,并鉴于其他答案和 cmets,我承认需要更改原始答案或为最不合格的答案。最后我保留原样,以供参考。
首先,也许也是最重要的一点,这个问题的公平答案取决于哈希码的预期用途:“好”[哈希函数...] 是什么意思?哈希将在哪里/如何使用? (例如,它是用于散列相对较短的输入键吗?是用于索引/查找目的,生成消息摘要还是其他用途?所需的散列码本身有多长,所有 32 位 [CRC32 或其衍生物],更多位,更少……等等?
OP 问题要求“更快 通用散列函数”,因此重点是速度(CPU 密集度较低和/或可以利用各种性质的并行处理的东西)。我们在这里可能会注意到,哈希码本身的计算时间通常只是哈希应用中问题的一部分(例如,如果哈希码的大小或其固有特性导致许多冲突,需要处理额外的周期和)。此外,“通用”的要求也留下了许多关于可能用途的问题。
考虑到这一点,一个简短而更好的答案可能是:
是的,CRC32C 在较新的英特尔处理器上的硬件实现可用于构建更快的哈希码;但是请注意,根据散列的具体实现及其应用,由于冲突的频率以及需要使用更长的代码,总体结果可能不是最佳的。此外,当然,应该仔细审查哈希的加密使用,因为 CRC32 算法本身在这方面非常薄弱。
原始答案引用了 Bret Mulvey 的一篇关于评估哈希函数的文章,正如 Mdlg 的答案中所指出的,这篇文章的结论对于 CRC32 是错误的,因为它是基于 CRC32 的实现有缺陷/有缺陷。尽管在 CRC32 方面存在重大错误,但本文提供了有关哈希算法一般属性的有用指导。这篇文章的 URL 现已失效;我在archive.today找到了它,但我不知道作者是否在其他地方有它,也不知道他是否更新了它。
此处的其他答案引用 CityHash 1.0 作为使用 CRC32C 的哈希库的示例。显然,这是在一些更长(超过 32 位)哈希码的上下文中使用的,但不适用于 CityHash32() 函数本身。此外,与生成哈希码的所有移位和混洗以及其他操作相比,City Hash 函数对 CRC32 的使用相对较少。 (这不是对我没有实践经验的 CityHash 的批评。我将通过对 CityHash 函数产生好的源代码的粗略审查,例如 ell 分布式代码,但没有明显更快比其他各种哈希函数。)
最后,您还可以在quasi duplicate question on SO 中找到有关此问题的见解。
原始答案和编辑(2010 年 4 月)
先验,这听起来是个坏主意!。
CRC32 不是为散列目的而设计的,它的分布可能不均匀,因此使其成为相对较差的散列码。此外,它的“加扰”能力相对较弱,导致单向散列非常差,就像在加密应用中使用的那样。
[BRB:我正在寻找有关该效果的在线参考资料...]
Google 的第一个 [keywords = CRC32 distribution] 似乎证实了这一点:
Evaluating CRC32 for hash tables
编辑:上面引用的页面,实际上complete article 提供了在哈希函数中查找内容的良好基础。
阅读 [快速] 这篇文章,确认了 一般 CRC32 不应用作散列的一揽子声明,但是,根据散列的特定目的,可能可以使用,在至少部分是 CRC32 作为哈希码。
例如,CRC32 代码的较低(或较高,取决于实现)16 位具有相对均匀的分布,并且只要不关心哈希码的加密属性(例如,事实相似的密钥产生非常相似的代码),有可能构建一个哈希码,例如,将两个 CRC32 代码的低 [或高] 16 位连接起来,由两个部分(或任何除法)产生原始密钥。
需要运行测试以查看内置 CRC32 指令相对于替代散列函数的效率是否会导致两次调用指令并将代码拼接在一起等的开销不会导致整体较慢的功能。