1 前言

前几天和一个大佬交流了几个问题,其中一个关于ID生成的问题推展到了哈希冲突和一个与之相关的一个数学趣题生日悖论。

当时对于两个事情的理解不够深刻,周末花时间仔细研究了一下,发现很有趣,于是觉得写一篇文章来和大家分享,今天的主题就是哈希冲突和生日悖论。

通过本文你将了解到以下内容:

  1. 哈希的映射压缩和冲突
  2. 生日悖论
  3. CRC32的冲突分析

2. 哈希映射压缩和冲突

哈希的本质就是数学,简单来说哈希函数实现了各种长度和形式的输入经过公开的哈希函数的运算生成一个固定长度的串,并且这个过程是单向不可逆的,也就是无法从哈希生成的串逆转为最初的输入。

听起来确实很神奇且有用,像一个万能胶囊,在一个小的范围内装了很多不一样的东西,原来有10MB的文件或者1GB的文件经过哈希运算后都会被映射到一个固定长度的串,可见压缩程度之大。

但是又不得不思考另外一个问题:输入是无穷尽的,生成的哈希串长度是固定的,那么必然面临着多个不一样的输入被映射压缩为一个相同的哈希串,就是无限集合映射有限集合导致的哈希碰撞或者叫哈希冲突。

举个栗子:

假如哈希串固定长度是二进制10bit,那么这个10bit空间可容纳的最大数量为2^10=1024,先不说无限输入集合,假如现在有2000个输入,在哈希函数均匀的前提下最少会有2000-1024=976个冲突。

看到这里,肯定有人会说那不用哈希了,但是哈希的压缩映射和不可逆性带来的便利确实有很大的吸引力,所以知难而退并不是个好主意。

我们知道幂次爆炸,所以如果把二进制位数扩展到32bit->64bit->128bit->256bit呢,2^32约为42亿,2^64约为1800多亿亿,128和256就更大了,貌似到了这里开始柳暗花明了,我们将长度增加空间就幂次增加,有效降低了冲突的概率,这也是当前主流的思路和方向。

小结:

哈希函数本身有很多种,底层的实现都有非常复杂的数学逻辑,均匀分布是哈希函数的一个重要特征,笔者才疏学浅并没有对哈希函数的数学原理做过多研究。

无限输入集合向有限集合的压缩映射是必然会出现碰撞的,解决碰撞的一个有效方法是增加映射空间长度,理解这一点就足够进行后面的阅读了,相信聪明的读者一定Get到笔者的意思了。

3.神奇的生日悖论

前面讨论了哈希冲突的必然性,那么我们不禁要思考:那我该选择多少bit的哈希函数才能避免碰撞呢?

其实面对这个问题的时候,我最开始是这么想的:使用32bit的哈希函数这样还有42亿个空间呢,那么产生哈希碰撞岂不是42亿分之一,貌似可以高枕无忧了,先看一个有趣的问题:

图片来自网络

生日悖论是指在不少于 23 个人中至少有两人生日相同的概率大于 50%。例如在一个 30 人的小学班级中,存在两人生日相同的概率为 70%。对于 60 人的大班,这种概率要大于 99%。从引起逻辑矛盾的角度来说,生日悖论并不是一种 “悖论”。但这个数学事实十分反直觉,故称之为一个悖论。

确实有一些违背直觉,一年365天怎么会有那么多人生日相同呢?然而这却是个事实。

来实际算一下这个问题:

假设有n个人在同一班级内,在不考虑特殊因素的前提下,例如闰年、双胞胎,假设一年365日出生概率是平均分布的,计算至少有两个人在同一日出生的概率是多少?

计算分析过程:

我们从其对立事件进行求解,找到n不断变化时对应的概率分布,p(n)表示n个人中每个人的生日都不同的概率,先考虑边界条件当n>365根据鸽巢原理其概率为0,n ≤ 365,则概率为:

在维基百科也有通用计算公式,一起看下:

图片来自 维基百科

再看下这个曲线和具体的离散化数据:

图片来自 维基百科

图片来自 维基百科

结论:

人数n=23时至少有两人生日相同的概率是50.7%,n=30时概率是70%,n=50时概率是97%,这么看来确实有悖直觉,但是这就是事实。

4. CRC32的碰撞概率

我们暂且以32位长度的CRC32算法为例来描述哈希碰撞的可能性。

简单来想CRC32的空间大小是42亿,但是实际上并不代码40亿左右数据才会出现碰撞,事实这个数据规模并不需要很大就会出现碰撞。

CRC32的碰撞问题本质上可以从生日悖论的角度来分析,相当于计算在有N个输入的情况下出现碰撞的概率。假设现在有K个输入,不出现冲突的概率计算(将42亿用S表示):

  • 第一个输入 1/S
  • 第二个输入 (S-1)/S
  • 第三个输入 (S-2)/S
  • ......
  • 第k个输入 (S-k+1)/S

这个计算过程和生日悖论基本是一样的,随着K的增加这个概率值下降非常快,笔者在网上找了一份CRC16-CRC64的冲突测试报告,可以看下:

//http://www.backplane.com/matt/crc64.html
output.16 Count 18134464/18200000
output.17 Count 18068928/18200000
output.18 Count 17937856/18200000
output.19 Count 17675712/18200000
output.20 Count 17151424/18200000
output.21 Count 16103198/18200000
output.22 Count 14061250/18200000
output.23 Count 10770169/18200000
output.24 Count 7092360/18200000
output.25 Count 4153742/18200000
output.26 Count 2259269/18200000
output.27 Count 1179721/18200000
output.28 Count 603421/18200000
output.29 Count 305089/18200000
output.30 Count 153722/18200000
output.31 Count 77254/18200000
output.32 Count 38638/18200000
output.33 Count 19232/18200000
output.34 Count 9652/18200000
output.35 Count 4914/18200000
output.36 Count 2343/18200000
output.37 Count 1204/18200000
output.38 Count 637/18200000
output.39 Count 302/18200000
output.40 Count 152/18200000
output.41 Count 75/18200000
output.42 Count 52/18200000
output.43 Count 21/18200000
output.44 Count 13/18200000
output.45 Count 7/18200000
output.46 Count 1/18200000
output.47 Count 1/18200000
output.48 Count 1/18200000
output.49 Count 0/18200000
output.50 Count 0/18200000
output.51 Count 0/18200000
output.52 Count 0/18200000
output.53 Count 0/18200000
output.54 Count 0/18200000
output.55 Count 0/18200000
output.56 Count 0/18200000
output.57 Count 0/18200000
output.58 Count 0/18200000
output.59 Count 0/18200000
output.60 Count 0/18200000
output.61 Count 0/18200000
output.62 Count 0/18200000
output.63 Count 0/18200000
output.64 Count 0/18200000

输入时1820w随机数据,上述数据给出了CRCx情况下1820w输入产生的碰撞数量,可以看到在CRC32中出现了38638个冲突,在CRC49中才出现0碰撞,所以冲突率还是很高的。

5.参考资料

  • 维基百科-生日悖论
  • CRC冲突测试报告

从生日悖论谈哈希碰撞相关推荐

  1. 怎么解决哈希冲突_从生日悖论谈哈希碰撞

    1 前言 前几天和一个大佬交流了几个问题,其中一个关于ID生成的问题推展到了哈希冲突和一个与之相关的一个数学趣题生日悖论. 当时对于两个事情的理解不够深刻,周末花时间仔细研究了一下,发现很有趣,于是觉 ...

  2. python生日悖论分析_生日悖论

    python生日悖论分析 If you have a group of people in a room, how many do you need to for it to be more like ...

  3. 哈希碰撞与生日相同概率

    一.哈希碰撞是什么? 所谓哈希(hash),就是将不同的输入映射成独一无二的.固定长度的值(又称"哈希值").它是最常见的软件运算之一. 如果不同的输入得到了同一个哈希值,就发生了 ...

  4. php 哈希碰撞攻击,浅谈php的哈希碰撞

    hash table在php中由为重要.存储变量的'符号表',array和object存储的数据结构,执行上下文的变量及函数均使用哈希表结构存储. Hash,简单来讲,是一种将任意长度的输入变换成固定 ...

  5. Comunion 区块链深度学习系列|哈希碰撞原理

    Comunion 是一个去中心化的(DAO) 组织协作网络,提供面向数字时代的全新商业基础设施和价值转化机制,致力于让劳动价值 像 资本一样自由流通.交易和积累. 本系列内容包含:基本概念及原理.密码 ...

  6. 【密码学/密码分析】生日悖论及生日攻击

    生日悖论及生日攻击 鸽巢原理:给定n个鸽巢,至少存在n+1只鸽子,那总是会发生碰撞. 概率环境:我们需要多少个物体(鸽子)使得发生碰撞的概率大于1/2? 答案是n1/2,而不是n/2. 举个例子,想象 ...

  7. 生日悖论与Hash函数的攻击

    生日悖论与Hash函数的攻击 生日悖论问题 什么是生日悖论问题 生日悖论问题求解 Hash函数的攻击 两个集合相交问题 Hash函数的攻击方法 Yuval攻击 生日悖论问题 什么是生日悖论问题 假定每 ...

  8. 关于生日悖论问题的验证

    昨天在网上看到一个非常有意思的问题: 数学老师和体育老师打赌,数据老师认为在他们有50个人的班级里有两个生日是同一天的同学的概率远超没有的概率,反之是体育老师的观点. 第一次看到的时候我觉得这特数学老 ...

  9. python生日悖论,Python的生日悖论

    在概率部分,生日悖论是一个非常著名的问题. 问题陈述-生日聚会上有几个人,有些人发生相同的生日碰撞.我们需要在有相同生日的基础上找到一个生日聚会的大概人数. 很有可能,我们知道前进的机会是1/2,就好 ...

最新文章

  1. 员工因公司而加入,却因主管而离开
  2. 案例驱动python编程入门-Python程序设计任务驱动式学习教程
  3. 派生类到基类的转换 和基类到派生类的转换
  4. 第三章 函数编程
  5. 正排索引(forward index)与倒排索引(inverted index)
  6. 近世代数--环同态--环的扩张定理
  7. 在github上面下载文件夹的方法666
  8. java quartz tomcat_Quartz Scheduler - 在Tomcat或应用程序jar中运行?
  9. Super Jumping! Jumping! Jumping!(HDU-1087)
  10. MySQL 当记录不存在时insert,当记录存在时update(ON DUPLICATE KEY UPDATE, REPLACE语句)...
  11. zabbix修改tomcat监控端口
  12. 汉字笔顺口诀_一帮40后理工男编出新型字典,《笔顺码字典》在汉首发
  13. ETL 工具的比较:Talend,Kettle,Informatica 等
  14. 程序设计语言的特性——心理特性、工程特性、技术特性
  15. 【与时俱进,智慧社区应运而生】
  16. 【格蕾读C++ Primer Plus】第九章 内存模型和名称空间
  17. 厦门大学计算机学院控制系,厦门大学
  18. 游戏美术师的火绝对不是捧出来的!不看不知道游戏模型师这么吃香
  19. Bluetooth LMP介绍
  20. matlab 二维矩形函数,科学网—利用MATLAB对非矩形域实现二维插值 - 张乐乐的博文...

热门文章

  1. 跨境电商维护商标的重要性和有效途径——成都扬帆志远教育公司
  2. Android WiFi开发教程
  3. 手机APP测试(二)
  4. 超分辨率重建学习总结、SR、super resolution、single image super resolution
  5. 听说,这些段子只有程序员才能看懂?
  6. ubuntu 18.04.6安装后无法上网
  7. Shell学习笔记(三)——获取文件夹里所有文件的文件名
  8. 怎样让计算机共享,普通打印机如何设置共享并且共享到其他电脑?
  9. 广义表的长度和广义表的深度
  10. TypeScript 初体验:开发工具准备