目录
一,什么是哈希函数?
二,大型网站如何利用 hash 函数保护用户密码?
三,为什么不是所有的 hash 函数都可以被用来加密?
四,哈希碰撞(hash collision)的解决方式
五,什么是好的哈希函数?
六,哈希函数的构造方法
七,为什么不能对可变的对象进行 hash 处理?
八,哈希表(hash table)原理
九,Python3.x 增加的随机性
十,其他 hash 算法
背景
哈希(hash)算法,原先是一种被用在资料编码中的技术,可以被用来加密要隐藏的资料,还可以被用来,比较不同文本的相似度。哈希算法属于信息摘要(Message Digest)算法。
区块链技术背后的底层原理之一,即为哈希算法。理解了哈希函数,自然就会理解区块链的挖矿模式。
全面的 hash 算法列表网址: ( http://burtleburtle.net/bob/hash/ )
1
一,什么是哈希函数?
哈希函数(hash function): 也称为「散列函数」或「杂凑函数」。
h = H(M)
哈希算法将任意长度的消息 M,映射成为一个长度较短且长度固定的值 H(M)。H(M)即为散列值或哈希值(hash value)。
哈希算法是一种信息摘要(Message Digest)算法。对象的 hash 值比原对象拥有更低的内存复杂度。
2
二,大型网站如何利用 hash 函数保护用户密码?
即使大型网站的数据库被攻破,也不会造成太大损失。为什么呢?这涉及到了哈希函数的两个主要特性:不可逆性与抗碰撞性。
利用哈希函数对用户密码进行加密:用户设置完密码后,会被转换成 hash 值,并保存到数据库中。如下图。被保存的只是转换后的哈希值,而不是原密码。
由于哈希(hash)函数是不可逆的,只能由输入产生输出,不能由输出产生输入。系统服务器无法根据每个 hash 值逆过来推算出原密码。因此即使是后台工作人员,也无法得知用户的原密码。
用户登录的时候,输入密码,经过 hash 操作后转换成 hash 值,再与数据库中被保存的 hash 值进行对比。hash 值完全一样,则密码正确。
3
三,为什么不是所有的 hash 函数都可以被用来加密?
不是所有的 hash 函数都可以被用来加密,这就涉及到了哈希碰撞(hash collision)。
对于 hash 算法,一般情况下,不同的数据会生成不同的哈希值。但是如果两个不同的数据,经过 Hash 函数计算后,得到的 Hash 值一样,则为哈希碰撞(collision)。 哈希碰撞无法被完全避免。只能降低其发生概率。
碰撞攻击则是找到另一个跟原密码具有相同 hash 值的字符串。
为了提高安全性,只有加密哈希函数(cryptgraphic hash functions)可以被用来加密。如 SHA256, SHA512, Ripemd, WHIRLPOOL 等 。这类函数的 hash 破解异常困难,几乎不太可能出现 hash 碰撞。
4
四,哈希碰撞(hash collision)的解决方式
一,开放寻址法(open addressing):
开放寻址法的总体设计原理为:出现哈希碰撞时,重新检测一个空闲位置,并插入。
线性探测器(Linear Probing)
二次探测法(Quadratic Probing)
随机探测法
双散列(Double hashing)
再哈希法
建立一个公共溢出区
二,拉链法
线性探测法:
线性探测法为开放寻址法最简单的一种实现。
线性探测法用来解决哈希碰撞的原理是:当某个被给定键在散列表中的对应单元已被占用时(即我们向当前哈希表写入数据时发生了冲突),会检测散列表中离冲突单元最近的空闲单元。并把该键值对写入到下一个不为空的位置。
只要哈希表未被填满,总能找到一个不发生冲突的单元。
再哈希法:
再哈希法用来解决哈希碰撞的原理是:两个值产生冲突时,通过下面算式,计算另一地址,直到不再冲突。
Hi = R * Hi(key) [i = 1,2,...k]
同样的关键字,同样的哈希函数,用不同的处理哈希碰撞的方法,得到的哈希函数值也不同。
5
五,什么是好的哈希函数?
哈希表的关键点就在于哈希函数的选择。
若对于关键字集合中的,任意一个关键字,经过哈希函数,映像到地址集合中,任何一个地址的概率是相等的,则为均匀(uniform)的哈希函数。也即好的哈希函数。
6
六,哈希函数的构造方法:
直接定址法
除留余数法
数字分析法
折叠法
平方取中法
直接定址法:取关键字,或关键字的某个线性函数值,为哈希地址。
即:H(key) = key 或 H (key) = a * key + b
链地址法:将所有相似关键词的记录存储在同一线性链表中。
7
七,为什么不能对可变的对象进行 hash 处理?
首先要了解两个概念,可哈希性(hashable)与不可哈希性(unhashable)。
可哈希性(hashable):可哈希的数据类型为不可变的数据结构(如字符串 srt,元组 tuple,对象集 objects 等)。这种数据被称为可哈希性。
不可哈希性:不可哈希的数据类型,为可变的数据结构(如字典 dict,列表 list 和集合 set 等)。
如果对可变的对象进行哈希处理,则每次对象更新时,都需要更新哈希表。这样我们则需要将对象移至不同的数据集,这种操作会使花费过大。
因此设定不能对可变的对象进行 hash 处理。
8
八,哈希表(hash table)原理
哈希表(hash table)|散列表,是根据关键码值进行访问的数据结构。通常提供查找(search),插入(insert),删除(delete)等操作。跟数组一样都是一种数据结构。与字典类似,通过键值对来保存数据。
目前大部分动态语言的实现中都使用了哈希表。有些语音将哈希表乘坐字典,但是哈希表跟字典并不完全相同。哈希表是弱类型的,而字典是强类型的。
哈希表操作的时间复杂度为0(1),这是它的一个重要优点。
9
九,Python3.x 增加的随机性
Python3.x添加了 hash 算法的随机性,以提高安全性,因此对于每个新的 python 调用,同样的数据源生成的结果都将不同。 下面为算法实例。
哈希方法有(MD5, SHA1, SHA256 与 SHA512 等)。常用的有 SH256 与 SHA512,即上文提到的加密哈希函数(cryptgraphic hash functions)。MD5 与 SHA1 不再常用。
MDH5 (不常用)
SHA1 (不常用)
SHA256 (常用)
SHA512 (常用)
10
十,其他 hash 算法**
1. simhash 算法:
这是一种局部敏感的 hash 算法,它产生的签名在一定程度上可以表征原内容的相似度。
可以被用来比较文本的相似度。
如下代码安装 simhash 模块。
pip3 installsimhash
2. Imagehash 算法:
Imagehash 算法为感知哈希算法(perceptual Hash Algorithm)。
常被用来检测图像和视频的差异。
如下代码安装 Imagehash 模块。
pip3 install simhash
例如:可以通过比较两张图片的 hash 值来判断相似度。下面为比较两张相似图片的代码示例。
输出为:
hash(image1) =00fd43c3**f**fffffff
hash(image2) =00fd43c3f**e**ffffff
从输出结果可以看到两张图片的 hash 值非常相似。相似的图片可以生成相似的哈希值是 Imagehash 的特点。
后续再详细更新哈希碰撞的解决方式
转载:https://blog.csdn.net/weinou314/article/details/106178888