哈希MurmurHash算法详解
文章目录
- 一、哈希函数
- 定义
- 特点
- 应用
- 常见哈希算法
- 二、murmurhash
- 定义
- 特点
- 应用
- 介绍
- 三、MurmurHash使用
- 四、性能测试
MurmurHash:(multiply and rotate) and (multiply and rotate) Hash,乘法和旋转的hash 算法。
一、哈希函数
定义
散列函数(英语:Hash function)又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。好的散列函数在输入域中很少出现散列冲突。
特点
加密:加密存在数据库中的密码(password)字符串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码。
压缩:把任意长度的输入通过散列算法变换成固定长度的输出。
应用
保护资料、确保传递真实的信息、散列表、错误校正、语音识别、信息安全。。。
常见哈希算法
MD系列(MD5)、SHA系列(SHA-1)、CRC,甚至JDK hashCode()也是哈希算法的一种。可以将他们分成三代:
第一代:SHA-1(1993),MD5(1992),CRC(1975),Lookup3(2006)
第二代:MurmurHash(2008)
第三代:CityHash, SpookyHash(2011)
分类可分为加密型、非加密型:
加密型:MD系列(MD5)、SHA系列(SHA-1)
非加密型:CRC、MurmurHash
这里记录一下在第二代中几乎一统江湖的MurmurHash。
二、murmurhash
定义
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。由Austin Appleby在2008年发明,并出现了多个变种,都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。
特点
1.快。
MurMurHash3 比 MD5 快。
2.低碰撞。
MurMurHash3 128 位版本哈希值是 128 位的,跟 MD5 一样。128 位的哈希值,在数据量只有千万级别的情况下,基本不用担心碰撞。
3.高混淆。
散列值比较“均匀”,如果用于哈希表,布隆过滤器等, 元素就会均匀分布。
应用
广泛应用于各开源产品,Java 界中 Redis,Memcached,Cassandra,Hadoop,HBase,Lucene,spark,nginx,常见的大数据库底层,都使用了这个算法作为底层的存储算法。
介绍
MD5 生成的哈希值是 128 比特的。这里的哈希值指的是二进制的值,而不是 HEX 或 base64 格式化后的人类可读的值。通常我们提到的 32 位 MD5 是指由 32 个字符组成的,HEX 格式的 MD5。MurMurHash 算法家族的最新一员为MurMurHash3,支持32位和128位,推荐使用128位的MurMurHash3。是原作者被Google挖去之后基于Murmur2的缺陷做了改进。
32位的,在某些场景下,比如哈希的对象长度小于 128 位,或者存储空间要求占用小,或者需要把字符串转换成一个整数,这一特性就能帮上忙。当然,32 位哈希值发生碰撞的可能性就比 128 位的要高得多。当数据量达到十万时,就很有可能发生碰撞。
贴一个网上的简单 MurMurHash2、MurMurHash3、MD5 的 benchmark:
https://github.com/spacewander/lua-resty-murmurhash3/blob/master/README.md#when-should-i-use-it
这里的结论:MurMurHash3 128 位版本的速度是 MD5 的十倍。有趣的是,MurMurHash3 生成 32 位哈希的用时比生成 128 位哈希的用时要长。原因在于MurMurHash3_128 针对现代 x64 平台cpu进行了优化。
Murmur是一个良好的通用散列函数系列,适用于非加密用法。MurmurHash提供以下好处:
简单(根据生成的汇编指令数量)。
良好的分布(几乎所有键组和铲斗尺寸均通过卡方检验。
好 雪崩 行为(最大偏差0.5%)。
良好的碰撞阻力(通过Bob Jenkin的frog.c酷刑测试。对于4字节键没有碰撞,没有小的(1到7位)差异)。
在Intel/AMD硬件上表现出色,散列质量和CPU消耗之间的良好折衷。
您当然可以使用它来散列UUID(就像任何其他高级散列函数一样:CityHash,Jenkins,Paul Hsieh等等)。现在,Redis bitset限制为4 GB位(512 MB)。因此,您需要将128位数据(UUID)减少到32位(散列值)。无论散列函数的质量如何,都会发生碰撞。
使用像Murmur这样的工程散列函数可以最大限度地提高分布质量,并最大限度地减少碰撞次数,但它不提供任何其他保证。
三、MurmurHash使用
1.导包
Java版:google guava 包中提供了使用工具类:
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
2.使用
import java.nio.charset.StandardCharsets;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;public class MurmurHashTest {public static void main(String[] args) {for (int i = 0; i < 100; i++) {String hexHashString = getHexHashString("qwerqwerqwer");System.out.println(hexHashString);}}public static String getHexHashString(String str) {HashFunction hashFunction = Hashing.murmur3_128();return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();}
}
四、性能测试
public class MurmurHashTest {public static void main(String[] args) {long l = System.nanoTime();for (int i = 0; i < 10000 * 10000; i++) {String hexHashString = getHexHashString("yzh123456qwer杨子");// System.out.println(hexHashString);}long time = System.nanoTime() - l;System.out.println("一亿数据,一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");long ns = time / (10000 * 10000);System.out.println("一亿数据,每条数据花费时间:" + ns + "纳秒");}public static String getHexHashString(String str) {HashFunction hashFunction = Hashing.murmur3_128();return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();}
}
结果:
一亿数据,一共花费时间:20秒
一亿数据,每条数据花费时间:200纳秒
MD5的性能测试:
public class MurmurHashTest {public static void main(String[] args) {long l = System.nanoTime();for (int i = 0; i < 10000 * 10000; i++) {String hexHashString = getHexMD5String("yzh123456qwer杨子");// System.out.println(hexHashString);}long time = System.nanoTime() - l;System.out.println("一亿数据,一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");long ns = time / (10000 * 10000);System.out.println("一亿数据,每条数据花费时间:" + ns + "纳秒");}public static String getHexMD5String(String str) {return DigestUtils.md5DigestAsHex(str.getBytes());}
}
MD5结果:
一亿数据,一共花费时间:32秒
一亿数据,每条数据花费时间:323纳秒
本人测试的字符串比较短,也可能是jar包不同版本以及使用的MacOS版本问题,虽然MurmurHash是比MD5快,但没有达到10倍的性能差距。
其它性能测试,含 hutool 包下的MurmurHash.hash64的使用:
package com.yy.armor.engine.core;import java.nio.charset.StandardCharsets;import cn.hutool.core.lang.MurmurHash;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.springframework.util.DigestUtils;public class MurmurHashTest {public static void main(String[] args) {String hexHashString = getHexHashStringWithGoogle128("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");System.out.println("getHexHashStringWithGoogle128=" + hexHashString);String hexHashString2 = getHexHashStringWithGoogle32("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");System.out.println("getHexHashStringWithGoogle32=" + hexHashString2);String hexHashString3 = getHexHashStringWithHutool64("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");System.out.println("getHexHashStringWithHutool64=" + hexHashString3);String hexHashString4 = getHexMD5String("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");System.out.println("getHexMD5String=" + hexHashString4);long l = System.nanoTime();for (int i = 0; i < 10000 * 10000; i++) {getHexHashStringWithGoogle128("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");}long time = System.nanoTime() - l;System.out.println("一亿数据,getHexHashStringWithGoogle128一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");long l2 = System.nanoTime();for (int i = 0; i < 10000 * 10000; i++) {getHexHashStringWithGoogle32("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");}long time2 = System.nanoTime() - l2;System.out.println("一亿数据,getHexHashStringWithGoogle32一共花费时间:" + time2 / (1000 * 1000 * 1000) + "秒");long l3 = System.nanoTime();for (int i = 0; i < 10000 * 10000; i++) {getHexHashStringWithHutool64("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");}long time3 = System.nanoTime() - l3;System.out.println("一亿数据,getHexHashStringWithHutool64一共花费时间:" + time3 / (1000 * 1000 * 1000) + "秒");long l4 = System.nanoTime();for (int i = 0; i < 10000 * 10000; i++) {getHexMD5String("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");}long time4 = System.nanoTime() - l4;System.out.println("一亿数据,getHexMD5String一共花费时间:" + time4 / (1000 * 1000 * 1000) + "秒");}public static String getHexHashStringWithGoogle128(String str) {HashFunction hashFunction = Hashing.murmur3_128();return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();}public static String getHexHashStringWithGoogle32(String str) {HashFunction hashFunction = Hashing.murmur3_32();return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();}public static String getHexHashStringWithHutool64(String data) {long hash64 = MurmurHash.hash64(data);return Long.toHexString(hash64);}public static String getHexMD5String(String str) {return DigestUtils.md5DigestAsHex(str.getBytes());}
}
结果:
getHexHashStringWithGoogle128=3f3d5e5f32f9fff6a34dfa6329a83bf7
getHexHashStringWithGoogle32=2cb92c51
getHexHashStringWithHutool64=4742386bfc5110a8
getHexMD5String=05fbb1053d692f9f6730d1a24e577a92
一亿数据,getHexHashStringWithGoogle128一共花费时间:36秒
一亿数据,getHexHashStringWithGoogle32一共花费时间:19秒
一亿数据,getHexHashStringWithHutool64一共花费时间:18秒
一亿数据,getHexMD5String一共花费时间:62秒
哈希MurmurHash算法详解相关推荐
- BiDi 算法详解及应用(一)
在开始本节内容之前,先对这个系列做一个简要的说明,在此系列里面会详细介绍以下几点内容: 什么是BiDi Unicode 的 BiDi 算法详解 ICU 对算法的实现和工业级应用 Html4 和 Htm ...
- Matlab人脸检测算法详解
这是一个Matlab人脸检测算法详解 前言 人脸检测结果 算法详解 源代码解析 所调用函数解析 bwlabel(BW,n) regionprops rectangle 总结 前言 目前主流的人脸检测与 ...
- 图论-最短路Dijkstra算法详解超详 有图解
整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...
- C++中的STL算法详解
1.STL算法详解 STL提供能在各种容器中通用的算法(大约有70种),如插入.删除.查找.排序等.算法就是函数模板,算法通过迭代器来操纵容器中的元素.许多算法操作的是容器上的一个区间(也可以是整个容 ...
- 粒子群(pso)算法详解matlab代码,粒子群(pso)算法详解matlab代码
粒子群(pso)算法详解matlab代码 (1)---- 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,C ...
- 基础排序算法详解与优化
文章图片存储在GitHub,网速不佳的朋友,请看<基础排序算法详解与优化> 或者 来我的技术小站 godbmw.com 1. 谈谈基础排序 常见的基础排序有选择排序.冒泡排序和插入排序.众 ...
- 目标检测 RCNN算法详解
原文:http://blog.csdn.net/shenxiaolu1984/article/details/51066975 [目标检测]RCNN算法详解 Girshick, Ross, et al ...
- Twitter-Snowflake,64位自增ID算法详解
Twitter-Snowflake,64位自增ID算法详解 from: http://www.lanindex.com/twitter-snowflake%EF%BC%8C64%E4%BD%8D%E8 ...
- 数据结构与算法详解目录
数据结构与算法详解是一本以实例和实践为主的图书,主要是经典的数据结构与常见算法案例,来自历年考研.软考等考题,有算法思路和完整的代码,最后提供了C语言调试技术的方法. 后续配套微课视频. 第0章 基 ...
最新文章
- ML:基于自定义数据集利用Logistic、梯度下降算法GD、LoR逻辑回归、Perceptron感知器、SVM支持向量机、LDA线性判别分析算法进行二分类预测(决策边界可视化)
- 2020年第十一届蓝桥杯 - 省赛 - C/C++研究生组 - F.成绩分析
- tinyxml在linux和windows下的编译及使用详解
- C语言 计算结构体大小
- 文献学习(part13)--A Sober Look at the Unsupervised Learning of Disentangled...
- UVALive 4329 Ping pong
- leetcode-345-Reverse Vowels of a String
- sql server 约束 查找
- 苹果12隔空投送显示无法连接服务器,iOS设备隔空投送功能无法使用该如何解决...
- (12) 基于深度时空残差网络ResNet的城市交通流预测
- 关于IDEA中使用git更新代码,会覆盖掉未提交的新代码解决问题
- 阿尔法编程python答案_C语言程序设计-阿尔法编程(编程答案)
- LabVIEW基础-内存优化
- 【基础】Linux 常用操作
- 最快速的文件传输软件,解析镭速文件传输软件
- linux宝塔原理,linux宝塔是干嘛的
- 婴儿认知的血流动力学研究
- varbinary转换成字符串
- Android电视清理系统应用,智能电视删除自带软件,这个方法最简单!
- r与python语法_Python和R:我推荐Python的几大理由