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到笔者的意思了。

神奇的生日悖论

前面讨论了哈希冲突的必然性,那么我们不禁要思考:那我该选择多少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%,这么看来确实有悖直觉,但是这就是事实,亲爱的读者不要惊讶,世界依然美好,大白依然推出好文章。

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碰撞,所以冲突率还是很高的。

参考资料

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

怎么解决哈希冲突_从生日悖论谈哈希碰撞相关推荐

  1. 从生日悖论谈哈希碰撞

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

  2. 哈希(解决哈希冲突,封装map/set,哈希的应用{位图/布隆过滤器})

    文章目录 如何解决哈希冲突: ①闭散列:也叫开放定址法,如果发送哈希冲突了,就去找下一个空位置 ②开散列 -- 拉链法/哈希桶 封装map和set 哈希表的代码 封装的unordered_set 封装 ...

  3. 获取文件哈希值_图解:什么是哈希?

    为什么要有哈希? 假设我们要设计一个系统来存储将员工手机号作为主键的员工记录,并希望高效地执行以下操作: 插入电话号码和相应的信息.(插入) 搜索电话号码并获取信息.(查找) 删除电话号码及相关信息. ...

  4. 计算机网络与通信pdf谢希仁_考研刷题资料谢希仁《计算机网络》(第7版)配套题库【考研真题精选(部分视频讲解)+章节题库】...

    谢希仁<计算机网络>(第7版)配套题库[考研真题精选(部分视频讲解)+章节题库] 本书是谢希仁<计算机网络>(第7版)教材的配套题库,主要包括以下内容: 第一部分为考研真题精选 ...

  5. 哈希表查找失败的平均查找长度_你还应该知道的哈希冲突解决策略

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/5vxYoeARG1nC7Z0xTYXELA 作者:Xuegui Chen 哈希是一种通过对数据 ...

  6. 哈希密码_哈希生日和密码

    哈希密码 什么是哈希函数? (What is a Hash function?) It's an algorithm that maps an input of arbitrary length to ...

  7. *8.哈希冲突是什么?以及如何解决哈希冲突

    哈希表:又叫散列表.是根据关键码值而直接进行访问的数据结构哈希表一个映射表,就是通过哈希函数算法,有的一个多对一的映射. 那哈希表有什么用呢? 很明显能加快查找速度.举个例子,你在查字典的时候,如果不 ...

  8. 【C++】哈希详解--哈希冲突解决办法

    文章目录 1.哈希概念 2.哈希碰撞(哈希冲突) 2.1哈希冲突产生原因 2.1.1哈希函数设计原则 2.1.2常见哈希函数 2.2 处理哈希冲突的方法 1.闭散列 定义 1.1线性探测 1.2二次探 ...

  9. 哈希冲突与解决哈希冲突的两种方法

    哈希冲突与解决哈希冲突的两种方法 1.哈希冲突 2.解决哈希冲突的方法 (1)链接法 (2)开放寻址法 ①线性探查 ②二次探查 ③双重探查 注:本文注重对解决哈希冲突方法的介绍,而非对背后原理的介绍. ...

最新文章

  1. CCF发布2020-2021中国计算机科学技术发展报告
  2. python函数(三)
  3. java时间格式转换_Java中System.currentTimeMillis()计算方式与时间的单位转换
  4. 【控制】四旋翼无人机姿态角分析
  5. 知乎推荐页 Ranking 构建历程和经验分享
  6. Fast Paxos
  7. 人工智能红利渗透与爆发
  8. data fastboot 擦除_fastboot擦除恢复等待设备【专业修复数据】
  9. 在Flex组件外观实施中使用Scale9
  10. 游戏开发之多态及虚函数(C++基础)
  11. Win10下Eclipse运行环境的安装及使用
  12. ip段各个号段的含义
  13. Ubuntu 20.04系统中Sage(sagemath)安装及使用详细过程
  14. 2018-8-10-控件
  15. php微信红包雨效果,微信红包雨特效口令大全 微信红包雨特效口令有哪些
  16. 硕士论文查重率是多少?
  17. C++11 auto关键字的用法
  18. 深圳关内主要旅游景点地址和公交路线
  19. 自学python能干什么
  20. STM32之固件库的调用(参考洋桃电子视频)

热门文章

  1. DUILIB中获取flash,webbrowser control的方法
  2. admin及admin888 经过 md5加密后16位和32位代码
  3. 第二阶段 铁大Facebook——十天冲刺(七)
  4. apollo在liunx环境实战(三)
  5. CTF---Web入门第四题 Forms
  6. oracle高级查询用法
  7. 服务器搬迁之后的准备工作和应对
  8. SQL Server-聚焦SNAPSHOT基于行版本隔离级别详解(三十)
  9. The conversion of a varchar data type to a datetime data type resulted in an out-of-range value
  10. 第一部分:开发前的准备-第三章 Application 基本原理