MurmurHash简介
MurmurHash是一种非加密散列函数,名称来自两个基本操作,乘法(MU)和旋转(R)。与加密散列函数不同,它不是专门设计为难以被对手逆转,因此不适用于加密目的。在2018年迭代到了MurmurHash3版本,它可以生成32位或128位的哈希值。相较于其他哈希函数,MurmurHash对于规律性较强的 key,它的随机分布特征表现更良好。
优点
- 速度快
缺点
- 不保证安全性
使用方式
google的Guava的工具包提供了其实现。
代码示例
com.google.guava guava 31.1-jre
public static void main(String[] args) { String s = "abcd1"; HashFunction hash1 = Hashing.murmur3_128(); HashCode hashCode = hash1.hashString(s, StandardCharsets.UTF_8); System.out.println(hashCode.toString()); System.out.println(hashCode.asInt()); System.out.println(hashCode.asLong()); System.out.println(hashCode.hashCode());}
与加密哈希的速度对比
以下使用md5和murmurHash进行对比。代码示例如下:
public static void main(String[] args) throws NoSuchAlgorithmException { String s = "abcd1"; int times = 10000000; murmurTimeTest(times, s); md5TimeTest(times, s);}public static void md5TimeTest(int times, String s) throws NoSuchAlgorithmException { long startTime = System.currentTimeMillis(); MessageDigest md5 = MessageDigest.getInstance("md5"); for (int i = 0; i < times; i++) { md5.digest(s.getBytes(StandardCharsets.UTF_8)); } System.out.println(MessageFormat.format("md5 花费时间:{0} 毫秒", System.currentTimeMillis() - startTime));}public static void murmurTimeTest(int times, String s) { long startTime = System.currentTimeMillis(); HashFunction hash1 = Hashing.murmur3_128(); for (int i = 0; i < times; i++) { hash1.hashString(s, StandardCharsets.UTF_8); } System.out.println(MessageFormat.format("murmurHash 花费时间:{0} 毫秒", System.currentTimeMillis() - startTime));}
结果
- 1000w次
- 1亿次
可以看到生成的次数越多,时间相差倍数就越大。
总结
murmurHash对于一些不需要加密的场景比较适用,在这类场景下不容易因为hash算法的效率而影响系统的并发量,比如:生成短链接。