hash 哈希算法_哈希一致性算法

hash 哈希算法_哈希一致性算法文章目录一、哈希函数定义特点应用常见哈希算法二、murmurhash定义特点应用介绍三、MurmurHash使用四、性能测试MurmurHash:(multiplyandrotate)and(multiplyandrotate)Hash,乘法和旋转的hash算法。一、哈希函数定义散列函数(英语:Hashfunction)又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

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

一、哈希函数

定义

散列函数(英语: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 比特的。这里的哈希值指的是二进制的值,而不是 HEX 或 base64 格式化后的人类可读的值。通常我们提到的 32 位 MD5 是指由 32 个字符组成的,HEX 格式的 MD5。MurMurHash 算法家族的最新一员为MurMurHash3,支持32位和128位,推荐使用128位的MurMurHash3。是原作者被Google挖去之后基于Murmur2的缺陷做了改进。

32位的,在某些场景下,比如哈希的对象长度小于 128 位,或者存储空间要求占用小,或者需要把字符串转换成一个整数,这一特性就能帮上忙。当然,32 位哈希值发生碰撞的可能性就比 128 位的要高得多。当数据量达到十万时,就很有可能发生碰撞。

贴一个网上的简单 MurMurHash2、MurMurHash3、MD5 的 benchmark:

https://github.com/spacewander/lua-resty-murmurhash3/blob/master/README.md#when-should-i-use-it

这里的结论:MurMurHash3 128 位版本的速度是 MD5 的十倍。有趣的是,MurMurHash3 生成 32 位哈希的用时比生成 128 位哈希的用时要长。原因在于MurMurHash3_128 针对现代 x64 平台cpu进行了优化。

Murmur是一个良好的通用散列函数系列,适用于非加密用法。MurmurHash提供以下好处:

简单(根据生成的汇编指令数量)。
良好的分布(几乎所有键组和铲斗尺寸均通过卡方检验。
好 雪崩 行为(最大偏差0.5%)。
良好的碰撞阻力(通过Bob Jenkin的frog.c酷刑测试。对于4字节键没有碰撞,没有小的(1到7位)差异)。
在Intel/AMD硬件上表现出色,散列质量和CPU消耗之间的良好折衷。

您当然可以使用它来散列UUID(就像任何其他高级散列函数一样:CityHash,Jenkins,Paul Hsieh等等)。现在,Redis bitset限制为4 GB位(512 MB)。因此,您需要将128位数据(UUID)减少到32位(散列值)。无论散列函数的质量如何,都会发生碰撞。

使用像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();
    }
}

四、性能测试

public class MurmurHashTest {
 
    public static void main(String[] args) {
        long l = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            String hexHashString = getHexHashString("yzh123456qwer杨子");
            // System.out.println(hexHashString);
        }
        long time = System.nanoTime() - l;
        System.out.println("一亿数据,一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");
 
        long ns = time / (10000 * 10000);
        System.out.println("一亿数据,每条数据花费时间:" + ns + "纳秒");
    }
 
    public static String getHexHashString(String str) {
        HashFunction hashFunction = Hashing.murmur3_128();
        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
    }
}

结果:

一亿数据,一共花费时间:20秒
一亿数据,每条数据花费时间:200纳秒

MD5的性能测试:

public class MurmurHashTest {
 
    public static void main(String[] args) {
        long l = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            String hexHashString = getHexMD5String("yzh123456qwer杨子");
            // System.out.println(hexHashString);
        }
        long time = System.nanoTime() - l;
        System.out.println("一亿数据,一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");
 
        long ns = time / (10000 * 10000);
        System.out.println("一亿数据,每条数据花费时间:" + ns + "纳秒");
    }
 
    public static String getHexMD5String(String str) {
        return DigestUtils.md5DigestAsHex(str.getBytes());
    }
}

MD5结果:

一亿数据,一共花费时间:32秒
一亿数据,每条数据花费时间:323纳秒

本人测试的字符串比较短,也可能是jar包不同版本以及使用的MacOS版本问题,虽然MurmurHash是比MD5快,但没有达到10倍的性能差距。

其它性能测试,含 hutool 包下的MurmurHash.hash64的使用:

package com.yy.armor.engine.core;
 
import java.nio.charset.StandardCharsets;
 
import cn.hutool.core.lang.MurmurHash;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.springframework.util.DigestUtils;
 
public class MurmurHashTest {
 
    public static void main(String[] args) {
        String hexHashString = getHexHashStringWithGoogle128("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        System.out.println("getHexHashStringWithGoogle128=" + hexHashString);
        String hexHashString2 = getHexHashStringWithGoogle32("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        System.out.println("getHexHashStringWithGoogle32=" + hexHashString2);
        String hexHashString3 = getHexHashStringWithHutool64("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        System.out.println("getHexHashStringWithHutool64=" + hexHashString3);
        String hexHashString4 = getHexMD5String("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        System.out.println("getHexMD5String=" + hexHashString4);
 
        long l = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            getHexHashStringWithGoogle128("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        }
        long time = System.nanoTime() - l;
        System.out.println("一亿数据,getHexHashStringWithGoogle128一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");
 
        long l2 = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            getHexHashStringWithGoogle32("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        }
        long time2 = System.nanoTime() - l2;
        System.out.println("一亿数据,getHexHashStringWithGoogle32一共花费时间:" + time2 / (1000 * 1000 * 1000) + "秒");
 
        long l3 = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            getHexHashStringWithHutool64("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        }
        long time3 = System.nanoTime() - l3;
        System.out.println("一亿数据,getHexHashStringWithHutool64一共花费时间:" + time3 / (1000 * 1000 * 1000) + "秒");
 
        long l4 = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            getHexMD5String("user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
        }
        long time4 = System.nanoTime() - l4;
        System.out.println("一亿数据,getHexMD5String一共花费时间:" + time4 / (1000 * 1000 * 1000) + "秒");
    }
 
    public static String getHexHashStringWithGoogle128(String str) {
        HashFunction hashFunction = Hashing.murmur3_128();
        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
    }
 
    public static String getHexHashStringWithGoogle32(String str) {
        HashFunction hashFunction = Hashing.murmur3_32();
        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
    }
 
    public static String getHexHashStringWithHutool64(String data) {
        long hash64 = MurmurHash.hash64(data);
        return Long.toHexString(hash64);
    }
 
    public static String getHexMD5String(String str) {
        return DigestUtils.md5DigestAsHex(str.getBytes());
    }
}

结果:

getHexHashStringWithGoogle128=3f3d5e5f32f9fff6a34dfa6329a83bf7
getHexHashStringWithGoogle32=2cb92c51
getHexHashStringWithHutool64=4742386bfc5110a8
getHexMD5String=05fbb1053d692f9f6730d1a24e577a92
一亿数据,getHexHashStringWithGoogle128一共花费时间:36秒
一亿数据,getHexHashStringWithGoogle32一共花费时间:19秒
一亿数据,getHexHashStringWithHutool64一共花费时间:18秒
一亿数据,getHexMD5String一共花费时间:62秒
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180524.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Python 冒泡排序_python

    Python 冒泡排序_python要学习冒泡排序必须知道它的原理:冒泡排序算法的原理如下:比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。例子:1,2,3,4,5,6就拿1到6来举例子吧!这里面有n个数字,你要对其进…

    2022年10月16日
  • gridview属性_GridView

    gridview属性_GridViewGridView在生成HTML代码的时候会自动加上style=”border-collapse:collapse;”以及border=1,rules=”all”这些属性,这些在IE下都没什么影响,但是在FF下就会影响显示,style=”border-collapse:collapse;”;是由于设置了CellSpacing=”0″产生的,当设置CellSpacing=”1″后就没有,可以去掉sty

  • css3实现光标悬浮滚动菜单

    效果:http://hovertree.com/texiao/css3/21/本文所用到的CSS知识请点击效果展示也中第一和第二个链接。代码:转自:http://hovertree.com/h/bj

    2021年12月24日
  • 为什么投屏找不到设备(投屏电视显示无法访问服务器)

    现在液晶电视价格越来越便宜,很少的钱就可以买一台60寸以上的电视,那么使用电脑的朋友一定想要把画面投屏到电视上,用于玩游戏、看电影吧!Win10就有非常好用的投屏功能,很多朋友可能不知道如何操作,这里小编和大家分享下具体步骤:Win10投屏电视步骤如下:(以小米电视为例)1、首先将电脑连接无线WIFI。2、将电视也连接在同一个无线WIFI网络下。3、进入电视应用中,选择“无线显示”功能。(不同的型…

  • java静态变量加载顺序_内部类为什么不能有静态

    java静态变量加载顺序_内部类为什么不能有静态静态内部类加载顺序我们先来区分一下两个概念:类加载、加载。类加载的过程包括加载,初始化,验证,解析,准备,初始化等五个过程。加载是类加载的一部分。区分完这两个概念之后我们再来看下面的问题。我们声明一个类,这个类有个内部静态类。还有主函数,当我们启动程序之后,运行javaapplication……

    2022年10月10日
  • linux命令_linux挂载cifs报错

    linux命令_linux挂载cifs报错[pcd@localhostax_peta]$petalinux-config–get-hw-description../SG400_top_hw_platform_1INFO:Gettinghardwaredescription…cp:omittingdirectory‘/home/pcd/peta_prj/SG400_top_hw_platform_1/cache…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号