一.背景介绍
MurmurHash算法:高运算性能,低碰撞率,由Austin Appleby创建于2008年,现已应用到Hadoop、libstdc++、nginx、libmemcached等开源系统。2011年Appleby被Google雇佣,随后Google推出其变种的CityHash算法。官方只提供了C语言的实现版本。
Java界中Redis,Memcached,Cassandra,HBase,Lucene都用它。
在Java的实现,Guava的Hashing类里有,上面提到的Jedis,Cassandra里都有Util类。
但存在的问题是由于Java的数据类型long与C语言中无符号长整型uint64_t有区别,导致Java输出版本存在负数,针对这个问题进行了修改;另外需要注意的是中文不同编码(UTF-8或GBK)会导致输出结果的不同,使用中需要统一编码。
一.实现类
import java.math.BigDecimal; import java.nio.ByteBuffer; import java.nio.ByteOrder; /** * 一致性Hash的一种算法 高效低碰撞率 */ public class Murmurs { /** * murmur hash算法实现 */ public static Long hash(byte[] key) { ByteBuffer buf = ByteBuffer.wrap(key); int seed = 0x1234ABCD; ByteOrder byteOrder = buf.order(); buf.order(ByteOrder.LITTLE_ENDIAN); long m = 0xc6a4a7935bd1e995L; int r = 47; long h = seed ^ (buf.remaining() * m); long k; while (buf.remaining() >= 8) { k = buf.getLong(); k *= m; k ^= k >>> r; k *= m; h ^= k; h *= m; } if (buf.remaining() > 0) { ByteBuffer finish = ByteBuffer.allocate(8).order( ByteOrder.LITTLE_ENDIAN); // for big-endian version, do this first: // finish.position(8-buf.remaining()); finish.put(buf).rewind(); h ^= finish.getLong(); h *= m; } h ^= h >>> r; h *= m; h ^= h >>> r; buf.order(byteOrder); return h; } public static Long hash(String key) { return hash(key.getBytes()); } /** * Long转换成无符号长整型(C中数据类型) */ public static BigDecimal readUnsignedLong(long value) { if (value >= 0) return new BigDecimal(value); long lowValue = value & 0x7fffffffffffffffL; return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)); } /** * 返回无符号murmur hash值 */ public static BigDecimal hashUnsigned(String key) { return readUnsignedLong(hash(key)); } public static BigDecimal hashUnsigned(byte[] key) { return readUnsignedLong(hash(key)); } }
二.测试类
import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import static org.assertj.core.api.Assertions.assertThat; public class MurmurHashTest { private static final Logger logger = LoggerFactory.getLogger(MurmurHashTest.class); @Test public void test() throws IOException { assertThat(Murmurs.hashUnsigned("chenshuo").toString()).isEqualTo("5016608279269930526"); assertThat(Murmurs.hashUnsigned("shaoguoqing").toString()).isEqualTo("17121371936686143062"); assertThat(Murmurs.hashUnsigned("baozenghui").toString()).isEqualTo("5451996895512824982"); assertThat(Murmurs.hashUnsigned("05ff62ff6f7749ffff43ffff6673ff65").toString()).isEqualTo("10652549470333968609"); assertThat(Murmurs.hashUnsigned("hahahaha").toString()).isEqualTo("15134676900169534748"); assertThat(Murmurs.hashUnsigned("hahah1369531321aha5466sfdfaerttedddd56da").toString()).isEqualTo("6439159232526071817"); assertThat(Murmurs.hashUnsigned("测试汉字").toString()).isEqualTo("1146745369200541601"); assertThat(Murmurs.hashUnsigned("1234566大大21".getBytes("GBK")).toString()).isEqualTo("10129762727109086067"); assertThat(Murmurs.hashUnsigned("12345665哦4哦3我的妈呀21".getBytes("GBK")).toString()).isEqualTo("5141842319936259217"); } }
相关推荐
这对于分布式系统尤其重要,因为它可以保证不同节点之间的一致性。 5. **源码开放**:MurmurHash的源代码是开源的,这使得开发者可以自由地查看、使用和改进算法。在压缩包中的`murmurhash.c`文件就是MurmurHash的...
- **兼容性**: 考虑与其他语言或库的 MurMurHash3 实现保持一致,以确保跨平台的一致性。 - **错误处理**: 实现应处理无效的输入,如空字符串、负长度等,并提供清晰的错误信息。 在 `MurMurHash3-master` 压缩包中...
9. **测试**:为了确保哈希函数的正确性和一致性,项目可能包含了单元测试,使用了如Jest、Mocha等测试框架。 10. **应用场景**:MurmurHash3在前端项目中可能用于生成唯一ID、数据索引、缓存键、指纹识别等场景。 ...
一致性哈希(Consistent Hashing)是一种分布式哈希表(DHT, Distributed Hash Table)算法,主要用于解决在分布式系统中数据存储和检索的问题,尤其是在动态扩展集群节点时,能够尽可能地减少缓存重建,保持系统...
在Mycat的一致性哈希分片算法中,murmur算法是一个核心组件。murmur算法是一个非加密哈希函数,具有高速运算和良好的分布性。Mycat使用murmur算法将数据的哈希值映射到虚拟节点上,然后根据虚拟节点的映射关系将数据...
它提供了Python接口来调用MurmurHash2算法,使得Python开发者无需直接处理C++代码,也能利用MurmurHash2的高效性。Cymur通常包括以下功能: 1. **哈希函数接口**:提供一个简单的函数调用,如`murmurhash2(key, ...
Python3-mmhash是一个开源项目,它是MurmurHash2算法的Python3实现。MurmurHash2是一个非加密哈希函数,由Austin Appleby在2008年设计,广泛用于数据索引、数据去重和快速查找等场景。它的特点是速度快、散列冲突的...
3. **末尾处理**:对于最后一块不足完整块的数据,进行特殊处理以确保一致性。 4. **结束**:最后将计算得到的哈希值进行一次XOR操作,以提高分布均匀性。 以下是一个简化的C语言实现框架: ```c #include #...
相比于传统的Jenkins Hash或MurmurHash,AnchorHash可能更侧重于在特定场景下优化内存效率,尤其是在资源受限的环境中。 **3. Go-AnchorHash特点** - **内存效率高**:Go-AnchorHash 的设计重点在于降低内存使用,...
其中,MurmurHash系列算法以其高效、低冲突的特性脱颖而出,而Murmur3作为该系列的最新版本,更是备受瞩目。本文将深入探讨Murmur3非加密哈希算法的原理及其在Elixir语言中的具体实现。 Murmur3算法的设计目标是...
在Scala中,哈希函数扮演着重要的角色,特别是在数据处理、键值存储和一致性哈希等场景。本篇文章将深入探讨Scala中的哈希函数,尤其是快速非加密哈希函数,如MurmurHash3和XXHash。 哈希函数是将任意大小的数据...
Gossip协议的使用允许Cassandra在面对故障恢复和扩展节点时,能快速达成全网络内的一致性状态。 Token(令牌)在Cassandra中用于确定数据应该存储到哪个节点上。Cassandra使用Murmur3Hash算法来计算行键(Row key)...
3. **哈希计算**:使用Go的`hash`包,例如`hash/crc32`或`hash/murmur3`,计算窗口内的数据哈希。 4. **分块判断**:比较连续数据段的哈希值,当超过预设阈值(比如两个哈希值不同时)时,生成新块。 5. **块编码与...
2. **哈希函数的选择**:为了确保输入元素的哈希值均匀分布,wyhll可能会选择强一致性且速度快的哈希函数,如MurmurHash或CityHash。 3. **最大零位前缀的计算**:代码会使用位操作来快速查找最长的连续零位,这是...
更优化的策略可能是将元素的哈希值按某种顺序组合起来,如使用FNV-1a哈希算法或者MurmurHash等高效哈希函数。 其次,考虑到列表的可变性,使用列表作为字典键需要谨慎。一旦列表被用作键并添加到字典中,修改该列表...