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 bit。这里的哈希值指的是二进制的值,而不是 HEX 或 base64 格式化后的人类可读的值。通常我们提到的 32 位 MD5 是指由 32 个字符组成的,HEX 格式的 MD5。MurMurHash 算法家族的最新一员为MurMurHash3,支持32位和128位,推荐使用128位的MurMurHash3。是原作者被Google挖去之后基于Murmur2的缺陷做了改进。

32位的,在某些场景下,比如哈希的对象长度小于 128 位,或者存储空间要求占用小,或者需要把字符串转换成一个整数,这一特性就能帮上忙。当然,32 位哈希值发生碰撞的可能性就比 128 位的要高得多。当数据量达到十万时,就很有可能发生碰撞。

Murmur是一个良好的通用散列函数系列,适用于非加密用法。MurmurHash提供以下好处:

简单(根据生成的汇编指令数量)。
良好的分布(几乎所有键组和铲斗尺寸均通过卡方检验。
好 雪崩 行为(最大偏差0.5%)。
良好的碰撞阻力(通过Bob Jenkin的frog.c酷刑测试。对于4字节键没有碰撞,没有小的(1到7位)差异)。
在Intel/AMD硬件上表现出色,散列质量和CPU消耗之间的良好折衷。

您当然可以使用它来散列UUID(就像任何其他高级散列函数一样:CityHash,Jenkins,Paul Hsieh等等)。使用像Murmur这样的工程散列函数可以最大限度地提高分布质量,并最大限度地减少碰撞次数,但它不提供任何其他保证。

三、MurmurHash使用

1.导包

Java版:google guava 包中提供了使用工具类:

        <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.1.1-jre</version></dependency>

2.使用

import java.nio.charset.StandardCharsets;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;/*** @author yangzihe* @date 2021/8/14*/
public class MurmurHashTest {public static void main(String[] args) {for (int i = 0; i < 100; i++) {String hexHashString = getHexHashString("yzh123456qwer杨子");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;/*** @author yangzihe* @date 2021/8/14*/
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秒

再贴一个网上简单的 MurMurHash2、MurMurHash3、MD5 的 benchmark:

lua-resty-murmurhash3/README.md at master · spacewander/lua-resty-murmurhash3 · GitHub

这里的结论:MurMurHash3 128 位版本的速度是 MD5 的十倍。

MurmurHash 哈希算法相关推荐

  1. Murmurhash 哈希算法 介绍与实现

    最近在项目代码中看到了一种hash算法,以前没有遇见过,在此记录下来. 一.介绍   MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作. 由Austin Appleby在2008 ...

  2. java murmurhash实现_一致性哈希算法与Java实现

    一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N,key是数据的key,N是机器节点数 ...

  3. Algorithm:C++语言实现之Hash哈希算法相关(dbj2、sdbm、MurmurHash)

    Algorithm:C++语言实现之Hash哈希算法相关(dbj2.sdbm.MurmurHash) 目录 一.Hash知识 1.dbj2​ 2.sdbm​ 3.MurmurHash Hash Has ...

  4. 哈希算法——murmurhash一致性哈希算法

    Murmurhash: 是一种非加密型哈希函数,适用于一般的哈希检索操作.高运算性能,低碰撞率,由Austin Appleby创建于2008年,现已应用到Hadoop.libstdc++.nginx. ...

  5. 【算法】哈希算法——murmurhash一致性哈希算法

    Murmurhash: 是一种非加密型哈希函数,适用于一般的哈希检索操作.高运算性能,低碰撞率,由Austin Appleby创建于2008年,现已应用到Hadoop.libstdc++.nginx. ...

  6. 一文搞懂负载均衡中的一致性哈希算法

    一致性哈希算法在很多领域有应用,例如分布式缓存领域的 MemCache,Redis,负载均衡领域的 Nginx,各类 RPC 框架.不同领域场景不同,需要顾及的因素也有所差异,本文主要讨论在负载均衡中 ...

  7. 一致性哈希算法与Java实现

    来源:http://blog.csdn.net/wuhuan_wp/article/details/7010071 一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具 ...

  8. 面试官:怎么改进哈希算法实现负载均衡的扩展性和容错性?我:...

    面试官:怎么改进哈希算法实现负载均衡的扩展性和容错性? 什么是哈希算法 数据结构中我们学习过哈希表也称为散列表,我们来回顾下散列表的定义. 散列表,是根据键直接访问在指定储存位置数据的数据结构.通过计 ...

  9. 一致性哈希算法原理、避免数据热点方法及Java实现

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简 单哈 ...

最新文章

  1. 归并排序的实现及其优化(递归法)
  2. MySQL和sql获取当前时间是本月的第几周或本月第一天的问题
  3. mediawiki 搭建
  4. 释放mysql ibdata1文件_释放MySQL ibdata1文件的空间
  5. SUN公司经典linux教材转自http://blog.chinaunix.net/uid-20446831-id-1677336.html
  6. IIS 添加mime 支持 apk,exe,.woff,IIS MIME设置 ,Android apk下载的MIME 设置 苹果ISO .ipa下载mime 设置...
  7. python 线性回归 约束_python – Tensorflow:具有非负约束的线性回归
  8. php学生成绩管理系统完整源代码,PHP学生成绩管理系统
  9. Win8驱动的兼容性问题
  10. 使用echarts来显示世界地图和全国地图,并且可以下钻层级
  11. java计算机毕业设计Web前端开发技术儿童教育网站MyBatis+系统+LW文档+源码+调试部署
  12. HDU -2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(DP,贪心)
  13. php校花评比排名,投票|佛山“校花”颜值大比拼,快来选出你最爱的!
  14. SAP 采购订单入库——收货业务分析
  15. 驾校学员信息管理系统
  16. JavaScript归纳总结
  17. 至高荣誉:WPS制作荣誉证书(转)
  18. Linux系统安全及应用-grub菜单启用密码限制10
  19. formal Verification 形式验证 形式验证的最大障碍:误报(false positives)的危险 第9章
  20. AdaBoost算法讲解、举例

热门文章

  1. SQL Server跟踪(Trace)--阻塞跟踪日志
  2. 惊艳死你的各种好用工具
  3. 夜光祝愿大家 520 快乐
  4. 个人永久性免费-Excel催化剂功能第19波-Excel与Sqlserver零门槛交互-查询篇
  5. 银子寄售与道具拍卖系统
  6. 科大讯飞2020秋招
  7. 在阿里巴巴做了5年软件测试,12月无情被辞,想给划水的兄弟提个醒
  8. 智慧城市安全体系实例——智能门锁安全吗?
  9. Pbootcms网站防黑、防跨站的经验分享
  10. php将证书保存位pem格式,openssl-如何以.pem格式保存证书中的公钥