哈希编码(Hashing)是一种将任意长度的数据转换成固定长度的数值或字符串的算法过程
1.基本原理
哈希编码通过哈希函数来实现。哈希函数是一种特殊的数学函数,它接收输入数据(可以是文本、数字、文件等各种形式的数据),然后按照一定的规则进行计算,最终输出一个固定长度的哈希值。例如,常见的哈希函数有MD5,它会将输入数据转换成一个128位的哈希值,通常以32位十六进制数的形式表示。
哈希函数具有单向性,即从哈希值很难反向推导出原始数据。这是因为哈希函数的计算过程是复杂的,且可能存在多个不同的输入数据经过哈希函数计算后得到相同的哈希值(虽然这种情况在设计良好的哈希函数中发生的概率极低)。
2.主要特点
固定长度输出:
无论输入数据的大小如何,哈希函数的输出哈希值的长度是固定的。比如SHA-256算法,无论输入是一个字符还是一个很大的文件,输出的哈希值都是256位。
高效性:
哈希函数的计算速度通常很快,能够在较短的时间内完成对输入数据的处理并得到哈希值。这使得哈希编码在很多需要快速处理数据的场景中非常有用。
高抗碰撞性:
理想中的哈希函数应该很难找到两个不同的输入数据,使它们经过哈希函数计算后得到相同的哈希值。不过,由于输入数据的无限性和哈希值的有限性,碰撞(即不同的输入产生相同的哈希值)在理论上是不可避免的,但好的哈希函数会尽量降低碰撞的概率。
3.算法举例
SHA-0算法原理与示例
算法核心步骤
1. 数据填充
对输入数据进行补位,使总长度 ≡ 448 mod 512(补码规则:首位补1,后续补0)。
例:输入数据为 abc (二进制长度24位),需补 448-24=424 位,总长度448位。
2. 添加长度信息
在填充后的数据末尾附加原始数据长度(64位无符号整数,若原始长度 > 2^64,则取低64位)。
例: abc 原始长度24位,附加 0x0000000000000018 (24的十六进制),总长度512位(1个分组)。
3. 初始化哈希值(缓冲区)
用5个32位寄存器存储初始值:
A=0x67452301 , B=0xEFCDAB89 , C=0x98BADCFE , D=0x10325476 , E=0xC3D2E1F0 。
4. 分组处理(循环迭代)
将数据分为512位分组,每组拆分为16个32位子块( W0~W15 ),并扩展为80个子块( W0~W79 ):
Wt = S^1(Wt-3 XOR Wt-8 XOR Wt-14 XOR Wt-16) ( S^b 表示循环左移b位)。
对每个分组进行80轮迭代,每轮运算:
f = (B AND C) OR ((NOT B) AND D) (第0~19轮,逻辑函数)
temp = S^5(A) + f + E + Wt + 0x5A827999 (常数随轮次变化)
E = D , D = C , C = S^30(B) , B = A , A = temp 。
5. 合并结果
所有分组处理完毕后,将5个寄存器的值串联,得到160位哈希值。
示例计算(简化版)
输入: a (ASCII码0x61,二进制 01100001 )
1. 填充与长度附加
原始长度:8位 → 填充后数据: 01100001 1 000...0 (补440个0) + 0x0000000000000008 → 总长度512位。
2. 扩展子块(仅前4个)
W0=0x61000000 , W1=0x00000000 , ..., W15=0x00000008
W16 = S^1(W13 XOR W10 XOR W2 XOR W0) (实际需计算至W79)。
3. 首轮迭代(t=0)
f = (B AND C) OR ((NOT B) AND D) = (0xEFCDAB89 AND 0x98BADCFE) OR ((NOT 0xEFCDAB89) AND 0x10325476)
temp = S^5(A) + f + E + W0 + 0x5A827999 (具体数值需按位运算计算)。
4. 迭代80轮
合并寄存器值得到最终哈希值(实际结果为 0x2ef7bde608ce5404e97d5f042f95f0c9f28f5ac3 )。
5.示例
因为SHA_0被弃用了,这里用SHA_1示例:
import hashlib
# 加密字符串 "a"
message = "a".encode('utf-8')
sha1_hash = hashlib.sha1(message).hexdigest()
print("SHA-1 哈希值:", sha1_hash)
三、关键特性与缺陷
特性:输入敏感(1位变化导致哈希值剧变)、抗碰撞性(理论上难以找到不同输入产生相同哈希)。
缺陷:存在弱碰撞攻击(如1998年Marc Stevens等学者发现的碰撞实例),安全性低于后续SHA-1/SHA-256,已被弃用。
通过上述步骤,SHA-0将任意长度数据压缩为160位指纹,但其安全缺陷使其在现代密码场景中不再适用。
4.应用场景
数据完整性校验:
在文件传输或存储过程中,可以对文件进行哈希编码,得到一个哈希值。当需要验证文件是否被篡改时,再次对文件进行哈希编码,比较前后两次得到的哈希值是否一致。如果一致,说明文件在传输或存储过程中没有被篡改。
密码存储:
在用户登录系统时,系统不会直接存储用户的密码明文,而是存储密码的哈希值。当用户输入密码进行登录时,系统会对输入的密码进行哈希编码,然后将得到的哈希值与存储的哈希值进行比较,从而判断密码是否正确。这样即使存储的哈希值被泄露,攻击者也很难通过哈希值反向推导出用户的密码明文。
哈希表:
在数据结构中,哈希表是一种通过哈希函数将键映射到表中的位置来访问记录的数据结构。通过哈希编码,可以快速地定位数据,提高数据查找的效率。