1、该种散列算法求哈希值与MD5大致一样,但也有不同之处。
2、代码实现
K = ["5A827999", "6ED9EBA1", "8F1BBCDC", "CA62C1D6"]
f1 = lambda x, y, z: ((x & y) | ((~x) & z))
f2 = lambda x, y, z: (x ^ y ^ z)
f3 = lambda x, y, z: ((x & y) | (x & z) | (y & z))
f4 = lambda x, y, z: (x ^ y ^ z)
f5 = lambda x, n: (((x << n) | (x >> (32 - n))) & (int("ffffffff", 16)))
# 消息填充与分组
def MessageFill(message):
'''
args = {
对消息转换成十六进制,消息填充,补充长度,分组
message:输入需要求哈希值的字符串
返回分组,每个元素是128位十六进制字符串
}
'''
Hex_String = ''
for c in message:
Hex_String += hex(ord(c)).replace("0x", "") # 转16进制
if len(Hex_String) * 4 == 448: # 如果刚好消息为448位bit,则需要再添加512位
Hex_String += "80"
Hex_String = Hex_String.ljust(len(Hex_String) + 126, '0')
if len(Hex_String) * 4 % 512 != 448: # 消息填充
Hex_String += "80"
Hex_String = Hex_String.ljust(len(Hex_String) + (448 - len(Hex_String) * 4 % 512) // 4, '0')
l = len(message) * 8
if len(message) * 8 > pow(2, 64):
l = len(message) % pow(2, 64)
len_str = hex(l).replace("0x", '')
if len(len_str) % 2 != 0:
len_str = len_str.zfill(len(len_str) + 1) # 长度字符串
len_str = len_str.zfill(16)
Hex_String += len_str # 添加长度
Hex_List = []
for i in range(0, len(Hex_String), 128): # 将填充好的字符串进行分组
Hex_List.append(Hex_String[i:i + 128])
return Hex_List
def GetW(Y):
'''
args = {
返回X的值
Y:512位bit分组,字符串形式,128位
X1等:形如:["cccccccc","dddddddd"...]共16个,每个8位
返回X:形如[[],[],[],[]]
}
'''
W = []
for i in range(0, len(Y), 8):
W.append(Y[i:i + 8])
for i in range(16, 80):
temp = hex(f5(int(W[i - 16], 16) ^ int(W[i - 14], 16) ^ int(W[i - 8], 16) ^ int(W[i - 3], 16), 1)).replace("0x",
"").zfill(
8)
W.append(temp)
return W
def Compression_Fun(CV, W, K, FF):
'''
args = {
压缩函数
CV:128为bit串,十六进制表示,形如["aaaaaaaa","bbbbbbbb"..]
XX:X[k],字符串形式
TT:T[i],常数表值
round = 轮数
They_Count:步数
返回新的CV,128为bit串,十六进制表示,形如["aaaaaaaa","bbbbbbbb"..]
}
'''
temp1 = hex(FF(int(CV[1], 16), int(CV[2], 16), int(CV[3], 16))).replace("0x", "").zfill(8)
temp2 = hex((int(CV[4], 16) + int(temp1, 16)) % pow(2, 32)).replace("0x", "").zfill(8)
temp3 = hex((f5(int(CV[0], 16), 5) + int(temp2, 16)) % pow(2, 32)).replace("0x", "").zfill(8)
temp4 = hex((int(temp3, 16) + int(W, 16)) % pow(2, 32)).replace("0x", "").zfill(8)
temp5 = hex((int(temp4, 16) + int(K, 16)) % pow(2, 32)).replace("0x", "").zfill(8)
temp6 = hex(f5(int(CV[1], 16), 30)).replace("0x", "").zfill(8)
new_CV = [temp5, CV[0], temp6, CV[2], CV[3]]
return new_CV
def SHAGroup(Y, CV):
'''
args = {
处理每个分组HMD5函数
Y:每一个分组,128位16进制
CV:上一轮压缩后的值,第一轮为初始值,128为bit串,十六进制表示,形如["aaaaaaaa","bbbbbbbb"..]
返回新一轮压缩后的值CV
}
'''
W = GetW(Y)
CV1 = CV.copy()
fun = [f1, f2, f3, f4]
for j in range(4):
for i in range(20):
temp_CV = Compression_Fun(CV1, W[j * 20 + i], K[j], fun[j])
CV1 = temp_CV.copy()
temp_CV.clear()
new_CV = []
for i in range(5):
new_CV.append(hex((int(CV[i], 16) + int(CV1[i], 16)) % pow(2, 32)).replace("0x", "").zfill(8))
return new_CV
def SHA(message):
'''
args = {
MD5算法的总控函数
message:需要压缩的消息
返回压缩后的哈希值,十六进制
}
'''
HeX_list = MessageFill(message) # 消息填充
CV0 = ["67452301", "EFCDAB89", "98BADCFE", "10325476", "C3D2E1F0"]
CV = CV0.copy()
for i in HeX_list: # 每一个分组进行处理
temp_CV = SHAGroup(i, CV)
CV = temp_CV.copy()
temp_CV.clear()
MD5_string = ''
for i in CV:
MD5_string += i
return MD5_string
3、参考链接
MD5