# MurmurHash簡介 MurmurHash是一種非加密散列函數,名稱來自兩個基本操作,乘法(MU)和旋轉(R)。與加密散列函數不同,它不是專門設計為難以被對手逆轉,因此不適用於加密目的。在2018年迭代到了MurmurHash3版本,它可以生成32位或128位的哈希值。相較於其他哈希函數,M ...
MurmurHash簡介
MurmurHash是一種非加密散列函數,名稱來自兩個基本操作,乘法(MU)和旋轉(R)。與加密散列函數不同,它不是專門設計為難以被對手逆轉,因此不適用於加密目的。在2018年迭代到了MurmurHash3版本,它可以生成32位或128位的哈希值。相較於其他哈希函數,MurmurHash對於規律性較強的 key,它的隨機分佈特征表現更良好。
優點
- 速度快
缺點
- 不保證安全性
使用方式
google的Guava的工具包提供了其實現。
代碼示例
<!-- maven依賴 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
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演算法的效率而影響系統的併發量,比如:生成短鏈接。