介绍MurmurHash是一种非密码哈希函数(Non-cryptographichashfunction),适用于一般的哈希检索操作。与其他流行的哈希函数相比,MurmurHash的随机分布特性对于规律性强的键表现更好。常见的MD5和SHA1是Cryptographichashfunction(密码散列函数)散列算法测评杨宝华《区块链·原理、设计与应用》第五章密码学与安全技术中提到,一个优秀的散列算法将能够实现以下功能:给定明文和散列算法,散列价值可以在有限的时间和有限的资源内计算出来。给定(几个)Hash值,很难(基本不可能)在有限的时间内推导出明文;变化,新生成的Hash值应该差别很大;冲突避免很难找到两段内容不同的明文,使得它们的Hash值一致(发生冲突)。防撞有时也称为“抗碰撞”,分为“弱抗碰撞”和“强抗碰撞”。如果在给定的明文前提下找不到与其发生碰撞的其他明文,则该算法具有“弱抗碰撞性”;如果找不到任意两个发生哈希碰撞的明文,则称该算法具有“强碰撞抗性”。家族成员MurmurHash1,MurmurHash2,MurmurHash364bitlongPython3(mmh3)#signed>>>mmh3.hash64('CN305183362S')(-1993453447204570204,-4896406162740467071)#unsigned>>>mmh3.hash64('CN305183362S',signed=False)(16453290626504981412,13550337910969084545)>>>mmh3.hash('CN305183362S')2088819274Java(guava)importcom.google.common.hash.Hashing;importcom.google.common.primitives.UnsignedLong;importstaticcom.google.common.base.Charsets.UTF_8;publicclassMain{publicstaticvoidmain(String[]args){longsigned=Hashing.murmur3_128().hashString("CN305183362S",UTF_8).asLong();UnsignedLongunsigned=UnsignedLong.fromLongBits(signed);System.out.println(签名);//-1993453447204570204System.out.println(unsigned);//16453290626504981412inthash32=Hashing.murmur3_32().hashString("CN305183362S",UTF_8).asInt();System.out.println(hash32);//2088819274}}计算mmh3十六进制字符串Python3>>>importbinascii>>>importmmh3>>>binascii.b2a_hex(mmh3.hash_bytes('CN305183362S')).decode('utf8')'a4fb17cba6d455e4812ad28989780cbc'#32>128位>>hex(mmh3.hash128('CN305183362S'))'0xbc0c788989d22a81e455d4a6cb17fba4'Java借用BigIntegerimportjava.math.BigInteger;importorg.apache.commons.codec.digest.Murmurmon.apapi.comport.com.lang.ArrayUtils;publicclassAppTester{publicstaticvoidmain(String[]args){finalbyte[]origin="CN305183362S".getBytes();long[]vec=MurmurHash3.hash128(origin,0,origin.length,0);//将long转换为BigIntegerBigIntegerbigInteger0=BigInteger.valueOf(vec[0]);BigIntegerbigInteger1=BigInteger.valueOf(vec[1]);//将BigInteger转换为byte[]byte[]array0=bigInteger0.toByteArray();byte[]array1=bigInteger1.toByteArray();//反转byte[](大小结束转换)ArrayUtils.reverse(array0);ArrayUtils.reverse(array1);//将byte[]转换为无符号整数并转换为十六进制字符串Stringpart0=(newBigInteger(1,array0)).toString(16);字符串part1=(newBigInteger(1,array1)).toString(16);System.out.println(part0+part1);//a4fb17cba6d455e4812ad28989780cbc}}借用ByteBuffer(好文推荐:byte,bytearrayandint,longinJavaconvert)importjava.nio.ByteBuffer;导入org.apache.commons.codec.digest.MurmurHash3;导入org.apache.commons.lang.ArrayUtils;publicclassAppTester{publicstaticvoidmain(String[]args){finalbyte[]origin="CN305183362S".getBytes();long[]vec=MurmurHash3.hash128(origin,0,origin.length,0);ByteBufferbuf0=ByteBuffer.allocate(8);ByteBufferbuf1=ByteBuffer.allocate(8);buf0.putLong(0,vec[0]);buf1.putLong(0,vec[1]);byte[]array0=buf0.putLong(0,vec[0]).array();byte[]array1=buf1.putLong(0,vec[1]).array();ArrayUtils.reverse(array0);//反转byte[](字节序转换)ArrayUtils.reverse(array1);//反转byte[](字节序转换)buf0.put(array0,0,array0.length).flip();buf1.put(array1,0,array1.length).flip();Stringpart0=String.format("%x",buf0.getLong());Stringpart1=String.format("%x",buf1.getLong());System.out.println(part0+part1);//a4fb17cba6d455e4812ad28989780cbc}}通俗易懂版,无需处理字节importorg.apache.commons.codec.digest.MurmurHash3;publicclassAppTester{publicstaticvoidmain(String[]args){finalbyte[]origin="CN305183362S".getBytes();long[]vec=MurmurHash3.hash128(origin,0,origin.length,0);Stringpart0=String.format("%x",vec[0]);Stringpart1=String.format("%x",vec[1]);字符串行="";//反转前半部分(字节序转换)for(inti=0;i<8;++i){line+=part0.substring(14-2*i,16-2*i);}//反转后半部分(Endian转换)for(inti=0;i<8;++i){line+=part1.substring(14-2*i,16-2*i);}System.out.println(行);//a4fb17cba6d455e4812ad28989780cbc}}googleguava(推荐)importcom.google.common.hash.Hashing;importstaticcom.google.common.base.Charsets.UTF_8;publicclassMain{publicstaticvoidmain(String[]args){Stringmmh3=Hashing.murmur3_128().hashString("CN305183362S",UTF_8).toString();System.out.println(mmh3);//a4fb17cba6d455e4812ad28989780cbc}}Node.jsMurmurHash3js在线测试:http://murmurhash.shorelabs。com/varmurmurHash3=require("murmurhash3js");letline=murmurHash3.x64.hash128("CN305183362S");console.log(line);//e455d4a6cb17fba4bc0c788989d22a81letnewLine="";//反转前半部分(字节序转换)for(leti=0;i<8;++i){newLine+=line.slice(14-2*i,16-2*i);}//反转后半部分(字节序转换)for(leti=0;i<8;++i){newLine+=line.slice(30-2*i,32-2*i);}反对唯一的日志(新行);//a4fb17cba6d455e4812ad28989780cbc本文来源qbitsnap
