【基础算法】简单了解一下常见的几种散列算法?
简单了解一下常见的几种散列算法?
如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!博客目录 | 先点这里
- 前提概念
- 好的哈希函数
- MD5 与 SHA
- MD5
- SHA 家族
- CRC
- MurmurHash
- times31/33
- times33
- times31
前提概念
好的哈希函数
- list of hash functions - wikipedia
好的哈希函数
好的哈希函数应该具备如下几种特性
- One-way 单向性
输出确定,且无法逆推出源数据,即单向散列函数 - Collision-resistant 抗冲突性
产生两个相同散列值的概率低 - Avalanche effect 雪崩效应
原始数据的微小改动,会导致散列值巨大的差异
MD5 与 SHA
MD5
md5 摘要算法,又称 “MD5 Message-Digest Algorithm”, 是一种不可逆向的密码散列函数。
特性
- 任意长度的原始数据,都将输出定长为
128
bit 的散列值 - 属于加密散列函数,计算较为耗费 CPU 资源
SHA 家族
SHA 家族的加密算法,又称 “Secure Hash Algorithm”, 是一个密码散列函数家族,发布了多个版本的 SHA 加密函数,如 SHA-0,SHA-1,SHA-2,SHA-3 等
特性
- 大部分仅支持
2^64 -1
的输入数据,根据不同的版本,有不同的位长,如 160,224,256,384,512 等,位数较长- sha-0,sha-1 输入不超过
2^64-1
, 输出定长160
bit
- sha-0,sha-1 输入不超过
对比
- MD5 和 SHA 通常都用在安全加密领域,因为都涉及数字加密,所以计算量都比较大,都比较消费 CPU 资源
CRC
CRC 算法 ("Cyclic Redundancy Check"
) ,又称循环冗余校验算法,是一种常用于通信链路检错,判断数据是否损坏的散列函数,但也不局限于此,它的基本原理是利用除法与余数的原理来做为错误侦测的
我们进行通信时的网络信道并不总是可靠的。为了增加可靠性,我们需要在传输数据后加上一些冗余的码字。如果接收方能够通过它们直接纠正错误,那么我们就称之为纠错码(Error Correcting Code),而 CRC 就是一种优秀的检错码,因为 CRC 具有良好的雪崩效应,即单个 bit 发生改变,也会导致散列值发生较大的改变,所以得以在通讯领域广泛应用。
原理
- 计算CRC的过程,就是用一个特殊的“除法”,来得到余数,这个余数就是CRC,而这里的除数则是一种 “模二除法”
- 通讯传送中,发送方会在原始数据末尾加上 CRC 检错码,并与接收方约定好 “除数 (多项式)”,最会得到余数 (CRC 值),接收方就会以收到的原始数据除以约定好的除数,看看最终的结果是否与 CRC 检错码一致
比如发送发传输了一段二进制数据,并附上 CRC 校验码。接收方就可以根据所接收到的二进制数据的 CRC 散列值与接收到的 CRC 检错码进行比对,如果不一致,就代表接收的数据可能在通讯传输过程中有缺失或错误
- 不要跑,CRC没这么难!(简单易懂的CRC原理阐述)
特性
- CRC 的协议有非常多种,比如 CCITT, MODBUS 等
- CRC 根据多项式的不同也会产生不同长度的检错码 (散列值),比如
CRC-8,CRC-16,CRC-32,CRC-64
, 分别对产生对应8,16,32,64
位长度的检错码,具有一定的数据压缩映射能力
代码
- redis-luttuce-crc16
MurmurHash
MurmurHash 是一种非加密型的散列函数,相比加密型散列函数,速度更快,差值最大可以达到几十倍,所以更适用于一般场景的哈希检索操作。MurmurHash 经历过多个版本的迭代,并有多种变种,当前最新版是 MurmurHash3。
且已被广泛应用在多种分布式系统中,比如 Redis, Kafka, Hbase, ElasticSearch
特性
- MurmurHash2 可以产生 32/64 bit 范围的散列值,MurmurHash3 可以产生 32/128bit 范围的散列值
- MurmurHash 支持加盐,即支持加一个种子值,而获得不同的 hash 规律,可以防止哈希洪水攻击(Hash-Flooding Attack
代码
public static void main(String[] args) {HashFunction function = Hashing.murmur3_32();System.out.println(function.hashBytes("abcd".getBytes()).asInt());// output = 1139631978}
- MurmurHash 的原理解析细节比较多,没看懂,就不贴了,这里是一个 Guava 提供的 murmur3 使用例子
- murmur3 可以使用在一般的哈希值计算,比如短链系统等
- redis-client-murmurhash
- guava-murmurhash3
MurmurHash3_最详细的介绍
times31/33
times33
Times33 算法是一个简单的对 “字符串” 进行哈希的函数,又称 “DJB Hash Function” or “DJBX33A”
原理
- 对字符串
s
进行逐个字符遍历,每次循环乘以33
,并加上 s[i] 字符的 ascii 码 , 然后求和即可 - 乘数是
33
, hash 初始值为5381
代码
private static int times33(String s) {int hash = 5381;char[] val = s.toCharArray();for (int i = 0; i < s.length(); i++) {hash = ((hash << 5) + hash) + val[i];}// hash is a positive integer,[0,2^31-1]hash &= Integer.MAX_VALUE;return hash;}
a * 33
=a * 2^5 + a
=a * 32 + a
hash &= 0x7fffffff
是为了获得 0 或 正整数,因为 Java 的 int 是有符号整数,只能表示 [0, 2^31 -1] 的整数
why
- 为什么取 33?
- 并没有人给于一个比较充分的理由说明,不过通过对[1,256]数值的实验证明,偶数的哈希分布非常差,冲突较高,所以就剩下 128 个奇数,并不是 33 就是最佳的选项
- 奇素数,哈希分布相比偶数更为良好
- 初始值为什么是 5381?
- 没有太多特别的理由,仅仅是在测试中,发现 5381 这个数字,在算法中哈希冲突和分布更好表现不错
- Reason for 5381 number in DJB hash function?
times31
times31 其实是 Java String hashcode 函数所采用的算法,因其思想类似 times33, 但数值采用 31 ,所以被习惯性称之 times31
原理
- 原理与 times33 一致,仅仅是乘数和初始值的选择不一样
- 乘数是
31
,初始值是0
代码
private static int times31(String s) {int hash = 0;char[] val = s.toCharArray();for (int i = 0; i < s.length(); i++) {hash = ((hash << 5) - hash) + val[i];}return hash;}
hash = ((hash << 5) - hash) + val[i]
等价于hash = 31 * hash + val[i]
- JDK 显式代码是
31 * hash
, 是因为编译器会自行优化
why
- 为什么取 31
31 和 33 都是奇素数,理由其实跟 times33 差不多,都是实验数据中,采取比较好的奇素数
参考资料
Time33 算法 - @作者:wzcu
Reason for 5381 number in DJB hash function?
MurmurHash3_最详细的介绍 - @作者:旧夏季 听风起
哈希洪水攻击(Hash-Flooding Attack)?-@知乎
如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!
【基础算法】简单了解一下常见的几种散列算法?相关推荐
- 安全系列之——主流Hash散列算法介绍和使用
其他文章: 安全系列之--手写JAVA加密.解密 安全系列之--数据传输的完整性.私密性.源认证.不可否认性 安全系列之--主流Hash散列算法介绍和使用 安全系列之--RSA的公钥私钥有多少人能分的 ...
- MD5散列算法原理及实现
目录 一.什么是MD5 二.MD5的功能 三.抗膨胀性 四.可逆性 五.MD5是 加密算法吗? 六.MD5用途 1.防止被篡改 2.防止明文读取. 3.防止抵赖 七.MD5算法过程 主要过程描述 第一 ...
- 常见的几种图像特征提取算法
常见的几种图像特征提取算法 1. LBP算法(Local Binary Patterns,局部二值模式) 2.HOG特征提取算法(Histogram of Oriented Gradient) 3.S ...
- MD5消息摘要算法和SHA-1安全散列算法
MD5消息摘要算法和SHA-1 安全散列算法 MD5和SHA-1都是我们耳熟能详的术语了,很多人可能知道他们跟加密有关系,但是他们是怎么做到加密的,他们各自的特点又是什么.我来简单的讲一讲. MD5和 ...
- MD5单向散列算法详解
历史: MD5 叫信息-摘要算法,是一种密码的算法,它可以对任何文件产生一个唯一的MD5验证码,每个文件的MD5码就如同每个人的指纹一样,都是不同的,这样,一旦这个文件在传输过程中,其内容被损坏或者被 ...
- 散列算法和哈希表结构
散列算法和哈希表结构 散列算法和哈希表结构 算法概述 Hash ,一般翻译做" 散列" ,也有直接音译为" 哈希" 的,就是把任意长度的输入(又叫做预映射, p ...
- 安全系列之——主流 Hash 散列算法介绍和使用
这里填写标题 1. 安全系列之--主流 Hash 散列算法介绍和使用 1.1. Hash 散列算法介绍 1.2. Hash 散列算法的特征 1.3. 散列算法的使用 1.3.1. 文件传输 1.3.2 ...
- shiro进行散列算法操作
shiro最闪亮的四大特征:认证,权限,加密,会话管理 为了提高应用系统的安全性,这里主要关注shiro提供的密码服务模块: 1.加密工具类的熟悉 首先来个结构图,看看shiro提供了哪些加密工具类: ...
- 对称加密、非对称加密和散列算法
一.什么是对称加密技术? 对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥.信息接收双方都需事先知道密匙和加解密算法,且其密匙是相同的,之后便是对数据进行加解密了.对称加密算法用 ...
最新文章
- 人工智能加速期:“算法为王”还是“场景落地”优先 ?
- Login failed with an access denied error.
- jdbc中如何实现模糊查询
- 瑞士的迷人风光(转)
- SQLite中的SQL
- Linux学习之zImage内核镜像解压过程详解
- [Java基础]哈希值
- 慕课乐学python单元测试答案_中国大学慕课第三章单元测试答案_乐学软件工程免费答案...
- 中国·哈尔滨国际友好城市冰雪汽车挑战赛开赛
- IDEA 创建类注释模板
- (转)中国大学改名大全2007最新版(笑掉大牙)
- matlab基本函数的输入输出,Matlab函数的基本使用
- bom_clear.php,金蝶KIS专业版常用SQL语句
- STM32PCB原理图
- 终极.NET混淆器丨.NET Reactor产品介绍
- icon小图标集合网站
- 机器学习梯度下降法应用波士顿房价预测
- 51NOD L4-第三章 树 刷题记录-zyz
- HDU - 1686 Oulipo KMP
- Unity Ads 中国正式落地:做玩家喜欢的广告,为游戏加分