MD5密码
【题目】1) 实现MD5 Hash函数算法,具体要求:A. 实现MD5算法的消息压缩过程,任选一个大小为10M的word文档,并计算其Hash值(注意,计算的是包括文件头等在内的完整文件的Hash函数值,而不仅仅是文件内容的Hash函数值);【实现代码】#!/usr/bin/env python# -*- coding: utf-8 -*-"""Created
·
【题目】
1) 实现MD5 Hash函数算法,具体要求:
A. 实现MD5算法的消息压缩过程,任选一个大小为10M的word文档,并计算其Hash值(注意,计算的是包括文件头等在内的完整文件的Hash函数值,而不仅仅是文件内容的Hash函数值);
【实现代码】
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 3 19:32:17 2018
@author: HP
"""
from time import clock
#初始变量 小端字节序:书上A = 0x01234567 这是内存中的顺序,并不是说A的值为0x01234567
#在程序中应该把A赋值为0x67452301
A = '0x67452301'
B = '0xefcdab89'
C = '0x98badcfe'
D = '0x10325476'
#步函数
F = lambda x,y,z:((x&y)|((~x)&z))
G = lambda x,y,z:((x&z)|(y&(~z)))
H = lambda x,y,z:(x^y^z)
I = lambda x,y,z:(y^(x|(~z)))
#循环左移函数(x循环左移n位)
L = lambda x,n:(((x<<n)|(x>>(32-n)))&(0xffffffff))
#每轮16步循环左移的位数
s1 = (7,12,17,22)*4
s2 = (5,9,14,20)*4
s3 = (4,11,16,23)*4
s4 = (6,10,15,21)*4
#每轮16步M子组的排序
m_1 = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
m_2 = (1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12)
m_3 = (5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2)
m_4 = (0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9)
#4轮64步的T表
T = ['0xd76aa478', '0xe8c7b756', '0x242070db', '0xc1bdceee',
'0xf57c0faf', '0x4787c62a', '0xa8304613', '0xfd469501',
'0x698098d8', '0x8b44f7af', '0xffff5bb1', '0x895cd7be',
'0x6b901122', '0xfd987193', '0xa679438e', '0x49b40821',
'0xf61e2562', '0xc040b340', '0x265e5a51', '0xe9b6c7aa',
'0xd62f105d', '0x02441453', '0xd8a1e681', '0xe7d3fbc8',
'0x21e1cde6', '0xc33707d6', '0xf4d50d87', '0x455a14ed',
'0xa9e3e905', '0xfcefa3f8', '0x676f02d9', '0x8d2a4c8a',
'0xfffa3942', '0x8771f681', '0x6d9d6122', '0xfde5380c',
'0xa4beea44', '0x4bdecfa9', '0xf6bb4b60', '0xbebfbc70',
'0x289b7ec6', '0xeaa127fa', '0xd4ef3085', '0x04881d05',
'0xd9d4d039', '0xe6db99e5', '0x1fa27cf8', '0xc4ac5665',
'0xf4292244', '0x432aff97', '0xab9423a7', '0xfc93a039',
'0x655b59c3', '0x8f0ccc92', '0xffeff47d', '0x85845dd1',
'0x6fa87e4f', '0xfe2ce6e0', '0xa3014314', '0x4e0811a1',
'0xf7537e82', '0xbd3af235', '0x2ad7d2bb', '0xeb86d391']
#翻转十六进制数的顺序:'0x01234567' => '0x67452301'
def reverse_hex(hex_str):
hex_str = hex_str[2:]
hex_str_list = []
for i in range(0,len(hex_str),2):
hex_str_list.append(hex_str[i:i+2])
hex_str_list.reverse()
hex_str_result = '0x' + ''.join(hex_str_list)
return hex_str_result
#md5类
class MD5(object):
def __init__(self, plaintext):
self.plist = ["0x"+hex(x)[2:].rjust(2, '0') for x in plaintext]
self.plength = len(self.plist)*8
print(self.plength)
self.__fill()
def __fill(self):
#先填充一个10000000
self.plist.append('0x80')
#然后填充00000000直到剩下64位也就是8字节
while (len(self.plist)+8)%64 != 0:
self.plist.append('0x00')
#用消息长度(位)填满最后8字节
#举例长度为8, 我们填充的应该是倒置的0x0800000000000000
#只有这样在内存中的顺序才是0x000000000000000008, 而不是直接填充0x000000000000000008
hex_len = hex(self.plength)[2:]
hex_len = '0x' + hex_len.rjust(16, '0')
hex_len = reverse_hex(hex_len)[2:]
for i in range(0, len(hex_len), 2):
self.plist.append('0x' + hex_len[i:i+2])
print(self.plist)
#生成每轮的16个M子分组
def genM16(self, order, z):
#起始坐标
start = 64*z
result = []
for i in range(start, start+64, 4):
result.append("0x" + "".join((self.plist[i] + self.plist[i+1] + self.plist[i+2] + self.plist[i+3]).split('0x')[1:]))
result = list(map(lambda x: result[x], order))
return list(map(reverse_hex, result))
#对每轮的16步进行加密
def fun(self, fun_list, sfunc, m, s, n):
for i in range(16):
#模2^32次方加
xx = int(fun_list[0], 16) + sfunc(int(fun_list[1], 16), int(fun_list[2], 16), int(fun_list[3], 16)) + int(m[i], 16) + int(T[16*n+i], 16)
xx = xx&0xffffffff
#循环左移s[i]位
xx = L(xx, s[i])
#加B
xx = (xx + int(fun_list[1], 16))&0xffffffff
fun_list[0] = hex(xx)
#列表右移一位
x = fun_list.pop()
fun_list.insert(0, x)
print(fun_list)
return fun_list
def encrypt(self):
abcd_list = [A, B, C, D]
for i in range(0, len(self.plist)//64):
#把寄存器初始值存下来
AA, BB, CC, DD = abcd_list
#生成该组明文四轮的M列表
m_list1 = self.genM16(m_1, i)
m_list2 = self.genM16(m_2, i)
m_list3 = self.genM16(m_3, i)
m_list4 = self.genM16(m_4, i)
#进行4轮加密
abcd_list = self.fun(abcd_list, F, m_list1, s1, 0)
print("------------------------------------------")
abcd_list = self.fun(abcd_list, G, m_list2, s2, 1)
print("------------------------------------------")
abcd_list = self.fun(abcd_list, H, m_list3, s3, 2)
print("------------------------------------------")
abcd_list = self.fun(abcd_list, I, m_list4, s4, 3)
print("------------------------------------------")
#和初始值相加得到该组明文加密结果
output_a = hex((int(AA, 16) + int(abcd_list[0], 16))&0xffffffff)
output_b = hex((int(BB, 16) + int(abcd_list[1], 16))&0xffffffff)
output_c = hex((int(CC, 16) + int(abcd_list[2], 16))&0xffffffff)
output_d = hex((int(DD, 16) + int(abcd_list[3], 16))&0xffffffff)
abcd_list = [output_a, output_b, output_c, output_d]
print(abcd_list)
return abcd_list
#将加密函数得到的结果进行反转合并显示出来
def show_result(self, abcd_list):
result = ""
for x in abcd_list:
result += reverse_hex(x)[2:]
return result
if __name__=="__main__":
print("__________开始md5加密______________")
#计时
#读文件
fname = input("please enter filename: ")
start = clock()
f = open(fname, 'rb')
plaintext = f.read()
f.close()
#加密
md5 = MD5(plaintext)
ciphertext = md5.show_result(md5.encrypt())
#将密文写入文件
f = open(fname, 'w')
f.write(ciphertext)
f.close()
print("__________加密结束______________")
print("密文:%s" %ciphertext)
print("加密时长是:%.2f" %(clock()-start))
#print(md5.show_result(md5.encrypt()))
更多推荐
已为社区贡献5条内容
所有评论(0)