MurmurHash-这是什么?


75

我一直在试图对MurmurHash的功能有一个较高的了解。

我已经阅读了基本说明,但尚未找到何时使用它以及为什么使用的很好解释。我知道它很快,但是想知道更多。

我问了一个有关如何将UUID放入Redis位集中的相关问题,有人建议使用MurmurHash。它可以工作,但我想了解风险/好处。

Answers:


113

Murmur是一系列良好的通用哈希函数,适用于非加密用途。如Austin Appleby所述,MurmurHash具有以下优点:

  • 简单(就生成的汇编指令而言)。
  • 良好的分布(通过几乎所有键集和存储桶大小的卡方检验。
  • 良好的雪崩行为(最大偏差为0.5%)。
  • 良好的抗碰撞能力(通过了鲍勃·詹金(Bob Jenkin)的frog.c酷刑测试。4字节密钥不可能发生冲突,差异不大(1至7位)。
  • 在Intel / AMD硬件上具有出色的性能,在哈希质量和CPU消耗之间进行了很好的权衡。

您当然可以使用它来对UUID进行哈希处理(就像其他任何高级哈希函数一样:CityHash,Jenkins,Paul Hsieh's等)。现在,Redis位集限制为4 GB位(512 MB)。因此,您需要将128位数据(UUID)减少到32位(哈希值)。无论哈希函数的质量如何,都将发生冲突。

使用像Murmur这样的工程哈希函数可以最大程度地提高分发质量,并最大程度减少冲突次数,但是它没有其他保证。

以下是一些比较通用哈希函数质量的链接:

http://www.azillionmonkeys.com/qed/hash.html

http://www.strchr.com/hash_functions

http://blog.aggregateknowledge.com/2011/12/05/choosing-a-good-hash-function-part-1/

http://blog.aggregateknowledge.com/2011/12/29/choosing-a-good-hash-function-part-2/

http://blog.aggregateknowledge.com/2012/02/02/choosing-a-good-hash-function-part-3/


我尝试使用MurmurHash来哈希我的UUID,但是哈希函数为某些UUID返回了负ID。有谁知道如何解决这个问题?
seedhead

11
MurmurHash的C实现的输出是一个无符号整数……不能为负。也许您正在使用Java?在Java中,蒙上了符号整数无符号价值的长期底部的32位,你需要和使用0xffffffffL(见stackoverflow.com/questions/9578639/...
迪迪埃拉斯佩齐亚

您知道对此哈希有任何分析吗?它是通用的吗?它是2维独立的吗?
Thomas Ahle 2014年

@DidierSpezia为什么Math.abs()不够好?鉴于原始ID(无论是否为负)已经均匀分布,结果也将分布良好。
翼展

Math.abs()可能确实足够好……但是您损失了1位,因此冲突的可能性乘以2(即,您的哈希值是31位而不是32位)。
Didier Spezia

-2

MurmurHash可以返回负值,原始值与0x7fffffff相加,即value和0x7fffffff。当输入为正时,将返回原始值。当输入数字为负数时,返回的正值是原始值位与0x7fffffff的绝对值之和。注意:MurmurHash的返回值不能是固定长度。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.