高效的MurmurHash 算法实现
目录
前言:
MurmurHash 介绍
各语言版本Murmurhash算法实现
C# 版本的Murmurhash算法实现
c/c++版本Murmurhash算法实现
java版本Murmurhash算法实现
前言:
对与C#或其他语言,我们有时需要计算hashCode或计算一串字符串、类的唯一值。我们知道不同的语言版本所计算方法不一,但是都有相应的性能问题。MurmurHash 对于唯一值的计算相对就快速很多。
MurmurHash 介绍
MurmurHash 是一种高性能的哈希算法,由 Austin Appleby 在 2008 年创建。它是一种非加密哈希算法,可以快速地计算出任意数据的哈希值。
MurmurHash 算法的特点是快速、高效、低碰撞、低冲突,适用于各种哈希表、哈希集合、哈希映射等数据结构。它的哈希值分布均匀,哈希冲突率低,能够更好地处理哈希碰撞和哈希冲突。
MurmurHash 算法的原理是将输入数据分成若干个块,每个块都使用不同的哈希函数计算出一个哈希值,然后将这些哈希值进行混合和运算,得到最终的哈希值。MurmurHash 算法使用了一些技巧来保证哈希值的均匀分布,例如使用了随机数种子、对哈希值进行了混淆等。
MurmurHash 算法有多个版本,包括 32 位和 64 位版本,也有多个变种,例如 MurmurHash3、MurmurHash2、MurmurHash1 等。MurmurHash 算法的实现语言包括 C++、Java、C#、Python 等。
总之,MurmurHash 算法是一种高效、低冲突、低碰撞的哈希算法,适用于各种哈希表、哈希集合、哈希映射等数据结构,是一个非常优秀的哈希算法。
MurmurHash 算法相比于 hashCode 算法有以下优点:
-
更好的哈希性能:MurmurHash 算法在哈希性能方面比 hashCode 算法更优秀,因为它能够快速地计算出任意数据的哈希值。MurmurHash 算法的哈希性能取决于数据的分布情况,但是在大多数情况下,它都能够提供比较好的哈希性能。
-
更低的哈希冲突率:MurmurHash 算法在哈希冲突率方面比 hashCode 算法更优秀,因为它能够更好地处理哈希冲突。MurmurHash 算法使用了一些技巧来减少哈希冲突,例如使用了两个不同的哈希函数、对哈希值进行了混淆等。
-
更好的分布性:MurmurHash 算法的哈希值在分布性方面比 hashCode 算法更优秀,因为它能够更好地处理数据的分布情况。MurmurHash 算法使用了一些技巧来保证哈希值的均匀分布,例如使用了随机数种子、对哈希值进行了混淆等。
-
更少的哈希碰撞:MurmurHash 算法在哈希碰撞方面比 hashCode 算法更优秀,因为它能够更好地处理哈希碰撞。MurmurHash 算法使用了一些技巧来减少哈希碰撞,例如使用了两个不同的哈希函数、对哈希值进行了混淆等。
综上所述,MurmurHash 算法相比于 hashCode 算法具有更好的哈希性能、更低的哈希冲突率、更好的分布性和更少的哈希碰撞。因此,在需要高效的哈希算法时,MurmurHash 算法是一个更好的选择。
各语言版本Murmurhash算法实现
C# 版本的Murmurhash算法实现
使用第三方库 MurmurHash.Net 实现 MurmurHash 算法的示例代码:
using MurmurHash;byte[] data = Encoding.UTF8.GetBytes("hello world");
uint seed = 0;
uint hash = MurmurHash3.Hash32(data, seed);
在上面的代码中,我们使用 MurmurHash3.Hash32() 方法计算输入数据的哈希值。data 是输入数据的字节数组,seed 是一个种子值,hash 是计算出的哈希值。
如果您想自己实现 MurmurHash 算法,可以参考以下代码:
public static class MurmurHash {public static uint Hash32(byte[] data, uint seed) {const uint c1 = 0xcc9e2d51;const uint c2 = 0x1b873593;const uint r1 = 15;const uint r2 = 13;const uint m = 5;const uint n = 0xe6546b64;uint hash = seed;uint len = (uint)data.Length;int pos = 0;while (len >= 4) {uint k = BitConverter.ToUInt32(data, pos);k *= c1;k = (k << r1) | (k >> (32 - r1));k *= c2;hash ^= k;hash = (hash << r2) | (hash >> (32 - r2));hash = hash * m + n;len -= 4;pos += 4;}if (len > 0) {uint k = 0;for (int i = 0; i < len; i++) {k |= (uint)data[pos + i] << (8 * i);}k *= c1;k = (k << r1) | (k >> (32 - r1));k *= c2;hash ^= k;}hash ^= (uint)data.Length;hash ^= hash >> 16;hash *= 0x85ebca6b;hash ^= hash >> 13;hash *= 0xc2b2ae35;hash ^= hash >> 16;return hash;}
}
在上面的代码中,我们实现了 MurmurHash 算法的 32 位版本。data 是输入数据的字节数组,seed 是一个种子值,hash 是计算出的哈希值。
c/c++版本Murmurhash算法实现
#include
#include uint32_t murmurhash(const void* key, int len, uint32_t seed) {const uint32_t c1 = 0xcc9e2d51;const uint32_t c2 = 0x1b873593;const uint32_t r1 = 15;const uint32_t r2 = 13;const uint32_t m = 5;const uint32_t n = 0xe6546b64;const uint8_t* data = (const uint8_t*)key;const int nblocks = len / 4;uint32_t hash = seed;for (int i = 0; i < nblocks; i++) {uint32_t k = *(uint32_t*)(data + i * 4);k *= c1;k = (k << r1) | (k >> (32 - r1));k *= c2;hash ^= k;hash = (hash << r2) | (hash >> (32 - r2));hash = hash * m + n;}const uint8_t* tail = (const uint8_t*)(data + nblocks * 4);uint32_t k = 0;switch (len & 3) {case 3:k ^= tail[2] << 16;case 2:k ^= tail[1] << 8;case 1:k ^= tail[0];k *= c1;k = (k << r1) | (k >> (32 - r1));k *= c2;hash ^= k;}hash ^= len;hash ^= hash >> 16;hash *= 0x85ebca6b;hash ^= hash >> 13;hash *= 0xc2b2ae35;hash ^= hash >> 16;return hash;
}
在上面的代码中,我们实现了 MurmurHash 算法的 32 位版本。key 是输入数据的指针,len 是输入数据的长度,seed 是一个种子值,hash 是计算出的哈希值。
java版本Murmurhash算法实现
在 Java 中,我们可以使用 Guava 库或自己实现 MurmurHash 算法。
以下是一个使用 Guava 库实现 MurmurHash 算法的示例代码:
import com.google.common.hash.Hashing;byte[] data = "hello world".getBytes();
int seed = 0;
int hash = Hashing.murmur3_32(seed).hashBytes(data).asInt();
在上面的代码中,我们使用 Hashing.murmur3_32() 方法创建一个 MurmurHash 算法的实例,然后使用 hashBytes() 方法计算输入数据的哈希值。data 是输入数据的字节数组,seed 是一个种子值,hash 是计算出的哈希值。
如果您想自己实现 MurmurHash 算法,可以参考以下代码:
public static int murmurhash(byte[] data, int seed) {final int c1 = 0xcc9e2d51;final int c2 = 0x1b873593;final int r1 = 15;final int r2 = 13;final int m = 5;final int n = 0xe6546b64;int hash = seed;int len = data.length;int pos = 0;while (len >= 4) {int k = (data[pos] & 0xff) | ((data[pos + 1] & 0xff) << 8) | ((data[pos + 2] & 0xff) << 16) | ((data[pos + 3] & 0xff) << 24);k *= c1;k = (k << r1) | (k >>> (32 - r1));k *= c2;hash ^= k;hash = (hash << r2) | (hash >>> (32 - r2));hash = hash * m + n;len -= 4;pos += 4;}if (len > 0) {int k = 0;for (int i = 0; i < len; i++) {k |= (data[pos + i] & 0xff) << (8 * i);}k *= c1;k = (k << r1) | (k >>> (32 - r1));k *= c2;hash ^= k;}hash ^= data.length;hash ^= hash >>> 16;hash *= 0x85ebca6b;hash ^= hash >>> 13;hash *= 0xc2b2ae35;hash ^= hash >>> 16;return hash;
}
在上面的代码中,我们实现了 MurmurHash 算法的 32 位版本。data 是输入数据的字节数组,seed 是一个种子值,hash 是计算出的哈希值。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
