首先了解下加密哈希和非加密哈希,
加密哈希函数旨在保证安全性,很难找到碰撞。即:给定的散列h很难找到的消息m;很难找到产生相同的哈希值的消息m1和m2。
非加密哈希函数只是试图避免非恶意输入的冲突。作为较弱担保的交换,它们通常更快。如果数据量小,或者不太在意哈希碰撞的频率,甚至可以选择生成哈希值小的哈希算法,占用更小的空间。
评价一个哈希算法的好坏,人们通常会引用 SMHasher 测试集的运行结果。 Smhasher 测试Hash函数的功能,测试包括以下几个方面:
MurmurHash是一种经过广泛测试且速度很快的非加密哈希函数。它有Austin Appleby于2008年创建,并存在多种变体,名字来自两个基本运算,即multiply和rotate(尽管该算法实际上使用shift和xor而不是rotate)。
MurmurHash3可以产生32位或128位哈希,旧版本MurmurHash2产生32位或64位值,MurmurHash2A变体添加了Merkel-Damgard构造,以便可以逐步调用它。MurmurHash64A针对64位处理器进行了优化,针对32位处理器进行MurmurHash64B优化
MurmurHash2-160生成160位哈希,而MurmurHash1已过时,实现规范的实现是用C++实现的,但是有多种流行语言的有效移植,已被很多开源项目采用。
具有良好的分布性,适用于机器学习用例,例如特征哈希和随机投影,布隆过滤器中也有应用。 MurMurHash3 128 位版本的速度是 MD5 的十倍。MurMurHash3 生成 32 位哈希的用时比生成 128 位哈希的用时要长。原因在于生成 128 位哈希的实现受益于现代处理器的特性。32 位哈希值发生碰撞的可能性就比 128 位的要高得多,当数据量达到十万时,就很有可能发生碰撞。
Avalanche Test(雪崩测试) 这意味着输入的微小变化会导致输出发生显著变化,使其统计上看起来与随机变化没有差别。例如:MurmurHash3(“abd”,123)=454173339;MurmurHash3(“abe”,123)=4085872068
Chi-Squared Test(卡方检验) 均匀性:一般期望设计的哈希函数的哈希值均匀落入哈希空间。将哈希空间 n 等分, 得到 p个 哈希值, 那么平均落入每个哈希子空间的哈希值是 𝑓_0= p /n, 落入第 i个子空间的哈希值个数是𝑓_𝑖 。统计量 x^2表示𝑓_𝑖到均匀分布的偏离度。哈希函数均匀性可用卡方拟合优度检验来判断。
MurmurHash:名字由两个运算得来 “multiply” “rotate”。 算法的流程如下: 使用模拟退火算法求出了最合适的参数,“c1=0xcc9e2d51” “c2=0x1b873593” “m=0x5” “n=0xe6546b64” “Hash=seed”
假设MurmurHash3(“abcde”,123) 1. abcd变成16进制并分别左移(留下e) 0x61→0x61000000 (左移24位) 0x62→0x00620000 (左移16位) 0x63→0x00006300 (左移8位) 0x64→0x00000064 2. 相加,赋值给k K = 0x61626364
3. 对k,Hash进行操作。(初始哈希值是一个随机数)。 k=kc1 k=“rotate” k by 15 k=kc2 Hash=Hash xor k
Hash=“rotate” k by 13 Hash=Hash*m+n
4. 处理tail(remaining bytes) 先左移后运算··· 得到:Hash=Hash xor k
5. Hash=Hash xor “block’s length”
Hash=Avalanche(Hash)
Output(Hash)
CityHash是Google发布的字符串散列算法,和murmurhash一样,属于非加密型hash算法。CityHash算法的开发是受到MurmurHash的启发。优点是大部分步骤包含了至少两步独立的数学运算。缺点是代码较同类流行算法复杂。 Google 希望为速度而不是为了简单而优化,因此没有照顾较短输入的特例 。
https://github.com/hajimes/mmh3 pip install murmurhash3
import mmh3 mmh3.hash(‘foo’) # 32-bit signed int -156908512 mmh3.hash64(‘foo’) # two 64-bit signed ints (the 128-bit hash sliced in half) (-2129773440516405919, 9128664383759220103) mmh3.hash128(‘foo’) # 128-bit signed int 168394135621993849475852668931176482145 mmh3.hash_bytes(‘foo’) # 128-bit value as bytes ‘aE\xf5\x01W\x86q\xe2\x87}\xba+\xe4\x87\xaf~’ mmh3.hash(‘foo’, 42) # uses 42 for its seed -1322301282
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183965.html原文链接:https://javaforall.cn