`
gaozzsoft
  • 浏览: 424884 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

哈希算法与MurmurHash3

 
阅读更多

MurmurHash 哈希算法

 

MurmurHash:(multiply and rotate) and (multiply and rotate) Hash,乘法和旋转的hash 算法。

MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。目前已经被广泛应用到很多开源的项目当中,如Redis,Memcached,Cassandra,HBase,Lucene等。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。它的名字来源于两个基本操作,乘法(MU)和旋转(R),在它的内部循环中使用。与加密散列函数不同,它不是专门设计为难以被对手逆转,因此不适合用于加密目的。
一、哈希函数
定义
散列函数(英语:Hash function)又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。好的散列函数在输入域中很少出现散列冲突。
特点
加密:加密存在数据库中的密码(password)字符串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码。
压缩:把任意长度的输入通过散列算法变换成固定长度的输出。
应用
保护资料、确保传递真实的信息、散列表、错误校正、语音识别、信息安全。。。
常见哈希算法
MD系列(MD5)、SHA系列(SHA-1)、CRC,甚至JDK hashCode()也是哈希算法的一种。可以将他们分成三代:
第一代:SHA-1(1993),MD5(1992),CRC(1975),Lookup3(2006)
第二代:MurmurHash(2008)
第三代:CityHash, SpookyHash(2011)
分类可分为加密型、非加密型:
加密型:MD系列(MD5)、SHA系列(SHA-1)
非加密型:CRC、MurmurHash
这里记录一下在第二代中几乎一统江湖的MurmurHash。
 
二、MurmurHash
定义
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。由Austin Appleby在2008年发明,并出现了多个变种,都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。
特点
1.快。
MurMurHash3 比 MD5 快。
2.低碰撞。
MurMurHash3 128 位版本哈希值是 128 位的,跟 MD5 一样。128 位的哈希值,在数据量只有千万级别的情况下,基本不用担心碰撞。
3.高混淆。
散列值比较“均匀”,如果用于哈希表,布隆过滤器等, 元素就会均匀分布。
应用
广泛应用于各开源产品,Java 界中 Redis,Memcached,Cassandra,Hadoop,HBase,Lucene,spark,nginx,常见的大数据库底层,都使用了这个算法作为底层的存储算法。
介绍
MD5 生成的哈希值是 128 bit。这里的哈希值指的是二进制的值,而不是 HEX 或 base64 格式化后的人类可读的值。通常我们提到的 32 位 MD5 是指由 32 个字符组成的,HEX 格式的 MD5。MurMurHash 算法家族的最新一员为MurMurHash3,支持32位和128位,推荐使用128位的MurMurHash3。是原作者被Google挖去之后基于Murmur2的缺陷做了改进。
32位的,在某些场景下,比如哈希的对象长度小于 128 位,或者存储空间要求占用小,或者需要把字符串转换成一个整数,这一特性就能帮上忙。当然,32 位哈希值发生碰撞的可能性就比 128 位的要高得多。当数据量达到十万时,就很有可能发生碰撞。
Murmur是一个良好的通用散列函数系列,适用于非加密用法。MurmurHash提供以下好处:
简单(根据生成的汇编指令数量)。
良好的分布(几乎所有键组和铲斗尺寸均通过卡方检验。
好 雪崩 行为(最大偏差0.5%)。
良好的碰撞阻力(通过Bob Jenkin的frog.c酷刑测试。对于4字节键没有碰撞,没有小的(1到7位)差异)。
在Intel/AMD硬件上表现出色,散列质量和CPU消耗之间的良好折衷。
您当然可以使用它来散列UUID(就像任何其他高级散列函数一样:CityHash,Jenkins,Paul Hsieh等等)。使用像Murmur这样的工程散列函数可以最大限度地提高分布质量,并最大限度地减少碰撞次数,但它不提供任何其他保证。

三、MurmurHash使用

1.导包

 

Java版:google guava 包中提供了使用工具类:

 

<groupId>com.google.guava</groupId>

<artifactId>guava</artifactId>

<version>30.1.1-jre</version>

2.使用

 

import java.nio.charset.StandardCharsets;

import com.google.common.hash.HashFunction;

import com.google.common.hash.Hashing;

 

public class MurmurHashTest {

 

    public static void main(String[] args) {

        for (int i = 0; i < 100; i++) {

            String hexHashString = getHexHashString("qwerqwerqwer");

            System.out.println(hexHashString);

        }

    }

 

    public static String getHexHashString(String str) {

        HashFunction hashFunction = Hashing.murmur3_128();

        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();

    }

}

 

代码例子:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>20.0</version>
</dependency>

public class TestMurmurhash3 {
    public static void main(String[] args) {
        String myStr = "ehl-test111";
        String str = Hashing.murmur3_128().newHasher().putString(myStr, StandardCharsets.UTF_8).hash().toString();
        System.out.println("str is:::::"+ str);

        HashFunction function = Hashing.murmur3_32();
        HashCode hascode = function.hashString("hello1", Charset.forName("utf-8"));
        System.out.println(hascode.asInt());
        HashCode hascode2 = function.hashString("hello2", Charset.forName("utf-8"));
        System.out.println(hascode2.asInt());
        HashCode hascode3 = function.hashString("hello3", Charset.forName("utf-8"));
        System.out.println(hascode3.asInt());

        byte[] mm3_le = Hashing.murmur3_128().hashString("abc", Charset.forName("utf-8")).asBytes();
        System.out.println(Hashing.murmur3_128().hashString("abc", Charset.forName("utf-8")).asInt());
        byte[] mm3_be = Bytes.toArray(Lists.reverse(Bytes.asList(mm3_le)));
        System.out.println(new BigInteger(mm3_be).toString());
        System.out.println(Hashing.murmur3_128().newHasher().putString("abc", StandardCharsets.UTF_8).hash().toString());
        System.out.println(Hashing.murmur3_128().newHasher().putString("abc", StandardCharsets.UTF_8).hash().asInt());

        assertEquals("79267961763742113019008347020647561319",new BigInteger(mm3_be).toString());

        HashFunction hashFunction = Hashing.murmur3_128();
        String s2 = hashFunction.hashString(myStr, StandardCharsets.UTF_8).toString();
        System.out.println(s2);


    }


    public static String getHexHashString(String str) {
        HashFunction hashFunction = Hashing.murmur3_128();
        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
    }

    public static String getHexMD5String(String str) {
//        return org.springframework.util.DigestUtils.md5DigestAsHex(str.getBytes());
return DigestUtils.md5Hex(str.getBytes());
    }

}

 HIVE UDF函数封装:
package com.xxx.utils.hash;

import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.apache.hadoop.hive.ql.exec.UDF;

import java.nio.charset.StandardCharsets;

/**
 * TODO
*
 * @author User
 * @version 1.0
 * @date 2022/4/12 15:38
 */
public class MyHiveUdf extends UDF {

//    重载evaluate方法
//    进入hive客户端,添加jar包:hive> add jar /run/jar/udf_test.jar
//    创建临时函数:hive> CREATE TEMPORARY FUNCTION murmurhash3 AS 'com.ehl.utils.hash.MyHiveUdf';
//    hive> SELECT murmurhash3("gaozz") FROM scores;
//    hive> DROP TEMPORARY FUNCTION murmurhash3;
//    murmurhash3(concat("uid-",uid))   as uidHash,
//    murmurhash3(concat("cre-",credit_id))   as creditCardIdHash

public String evaluate(String inputStr){
        String str = Hashing.murmur3_128().newHasher().putString(inputStr, StandardCharsets.UTF_8).hash().toString();
//        HashFunction hashFunction = Hashing.murmur3_128();
//        String str =  hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
return str;
    }


}
HIVE SQL使用自定义函数:murmurhash3
//    murmurhash3(concat("uid-",uid))   as uidHash,
//    murmurhash3(concat("cre-",credit_id))   as creditCardIdHash
分享到:
评论

相关推荐

    MurMurHash3:MurMurHash3算法的纯C#实现

    ** MurMurHash3 算法概述 ** MurMurHash3 是一种非加密哈希函数,由 Austin Appleby 开发,被广泛应用于数据结构和分布式系统中,如 Hadoop、Redis 和其他数据库系统。它的主要特点是计算速度快且哈希冲突的概率...

    C语言哈希函数库murmur3.zip

    这是 Murmur3 哈希函数的 C 语言移植版本,Murmur3 是一个非加密的哈希算法,主要设计目的是快速和高质量,原有代码是 C 的,先移植到 C 并兼容标准 C 和 gcc 编译器。 标签:murmur3

    前端开源库-murmurhash3js-revisited

    4. **跨平台兼容**:由于murmurhash3js-revisited库在Node.js和浏览器环境下都能运行,开发者可以在前后端统一使用相同的哈希算法,简化了代码维护和移植。 5. **源码可读性**:开源库的代码通常具有良好的注释和...

    murmurhash

    《MurmurHash:高性能、低碰撞的哈希算法解析》 MurmurHash是一种广泛应用于数据处理和存储系统的非加密哈希函数,由Austin Appleby在2008年设计。它的主要特点在于提供了出色的运算性能和极低的哈希碰撞率,这使得...

    前端项目-murmurhash3js.zip

    4. **浏览器与服务器兼容性**:JavaScript实现的MurmurHash3可以在浏览器和服务器环境中运行,意味着它可以应用于Web应用的客户端和服务器端,如Node.js服务端开发。 5. **JavaScript语法**:理解这个项目的代码...

    murmur-hash:MurmurHash3 算法的 javascript 实现

    var murmurHash3 = require('murmur-hash').v3; 例子 // Return a 32bit hash as a unsigned int: &gt; murmurHash3.x86.hash32("I will not buy this record, it is scratched.") 2832214938 // Return a 128bit ...

    murmurhash-php:MurmurHash3PHP用户区实现

    由Gary Court创建的MurmurHash3 JavaScript版本的移植( ) 安装 使用: composer require lastguest/murmurhash 用法 您可以通过Murmur类的hash3静态方法检索哈希 &lt;?php use lastguest\ Murmur ; echo Murmur :...

    Python库 | murmurhash2-0.2.0-cp37-none-win_amd64.whl

    `murmurhash2-0.2.0` 这个版本可能提供了Python绑定,使得用户可以方便地在Python代码中调用C语言实现的MurmurHash2算法,从而获得更好的性能。 **安装与使用** 这个`.whl`文件是一种Python的轮子文件,它是预编译...

    Python库 | murmurhash-1.0.0-cp27-cp27mu-manylinux1_x86_64.whl

    例如,使用`murmurhash3_32` 函数,可以对字符串、字节对象等进行哈希运算。 ```python import murmurhash data = "Hello, World!" hash_value = murmurhash.murmurhash3_32(data) print("哈希值:", hash_value) `...

    murmur3:本机MurmurHash3 Go实现

    Austin Appleby的第三个MurmurHash修订版(aka MurmurHash3)的Native Go实现。 引用算法已被略微修改,以支持Go的标准所需的流模式。 基准测试 截至2014年6月12日(即接近go1.3),i7核心@ 3.4 GHz时的提示。 ...

    node-murmurhash:一个Node.js模块,用于优化MurmurHash算法JavaScript实现

    节点杂音 注意:这是,可移植到commonJS模块,该模块可以轻松地包含在node.js项目或浏览器中。 我不相信实施。 我只是让其他人更容易使用。 MurmurHash算法的优化... 同时支持MurmurHash算法的版本2和版本3: /

    7种Hash算法

    哈希算法能够将任意长度的输入(也叫做预映射或消息)转化为固定长度的输出,这个输出通常是一个二进制数字,称为哈希值。在本篇文章中,我们将深入探讨7种常见的哈希算法,以及如何使用C语言实现它们。 1. **MD5...

    murmurhash:Mur MurmurHash2的Cython绑定

    它是由Austin Appleby开发的一种哈希算法,以其快速、高效的特性而著名。MurmurHash2的主要优点在于它能够避免常见的哈希冲突,并且对于不同的输入大小,其计算速度保持相对一致。这种算法对输入数据进行多次混合...

    node-murmurhash-native:MurmurHash节点的本机绑定

    基于其他MurmurHash3 32位和128位渐进实现 流封装器,用于带有渐进式哈希器。类似于bi-api接口 渐进式哈希器的可序列化状态 哈希的BE或LE字节顺序变体 承诺包装 适用于大多数标准系统配置的预构建二进制文件 ...

    python3-mmhash:MurmurHash2 的 Python3 端口

    Python3-mmhash是一个开源项目,它是MurmurHash2算法的Python3实现。MurmurHash2是一个非加密哈希函数,由Austin Appleby在2008年设计,广泛用于数据索引、数据去重和快速查找等场景。它的特点是速度快、散列冲突的...

    PyPI 官网下载 | murmurhash-0.26.4-cp35-cp35m-macosx_10_6_intel.whl

    MurmurHash算法以其低冲突率和高性能而闻名,尤其适合用于需要高性能哈希计算的场景,如数据库索引、数据去重、键的生成等。 描述中的"资源来自pypi官网,解压后可用。资源全名:murmurhash-0.26.4-cp35-cp35m-...

    murmurhash-net:.NET murmurhash的实现

    .NET的哈希的实现 在撰写本文时,该库支持3种主要Murmur3变体:32位哈希(x86),128位...HashAlgorithm murmur128 = MurmurHash.Create128(managed: false); // returns a 128-bit algorithm using "unsafe" code with

    Mycat一致性哈希分片算法1

    在上面的示例中,我们定义了一个名为"sharding-by-murmur"的分片规则,使用 murmur 算法对数据进行哈希分片。该规则将根据数据的id列进行哈希映射,并将其分配到两个数据库节点中(count=2)。 在Mycat的一致性哈希...

    murmurhash:基于smhasher的导出跨平台murmurhash

    MurmurHash的最新版本是MurmurHash3,它在性能和散列质量上都有显著提升。 这个压缩包"murmurhash-master"包含了MurmurHash的源代码,是为.NET环境提供的实现。这意味着开发者可以在.NET平台上方便地使用MurmurHash...

    56丨算法实战(五):如何用学过的数据结构和算法实现一个短网址系统?1

    然而,哈希算法存在冲突的问题,即使MurmurHash的冲突概率较低,仍有可能出现两个不同的长网址映射到相同的短网址。为了解决这个问题,我们需要存储短网址和原始网址之间的映射关系。这可以通过自定义的存储系统或...

Global site tag (gtag.js) - Google Analytics