本文共 4756 字,大约阅读时间需要 15 分钟。
【题目】
1) 实现SHA1 Hash函数算法,具体要求:
A. 实现SHA1算法的消息压缩过程,任选一个大小为10M的word文档,并计算其Hash值(注意,计算的是包括文件头等在内的完整文件的Hash函数值,而不仅仅是文件内容的Hash函数值);
【实现代码】
#!/usr/bin/env python# -*- coding: utf-8 -*-"""Created on Sun Jan 7 15:29:18 2018@author: HP"""from time import clock#寄存器初始值A = "0x67452301"B = "0xefcdab89"C = "0x98badcfe"D = "0x10325476"E = "0xc3d2e1f0"#Krk1 = "0x5a827999" #"0x9979825a"k2 = "0x6ed9eba1" #"0xa1ebd96e"k3 = "0x8f1bbcdc" #"0xdcbc1b8f"k4 = "0xca62c1d6" #"0xd6c162ca"#4轮非线性函数Ch = lambda x, y, z: (x&y)^((~x)&z)Parity = lambda x, y, z: x^y^z #第四轮函数也是ParityMaj = lambda x, y, z: (x&y)^(x&z)^(y&z)#左移n位L = lambda x,n:(((x<>(32-n)))&(0xffffffff)) #翻转十六进制数的顺序:'0x01234567' => '0x67452301' def reverse_hex(hex_str): hex_str = hex_str[2:] hex_list = [] for i in range(0, len(hex_str), 2): hex_list.append(hex_str[i:i+2]) hex_list.reverse() return "0x" + "".join(hex_list) #SHA1类class SHA1(object): def __init__(self, plaintext): self.plist = ["0x" + hex(x)[2:].rjust(2, "0") for x in plaintext] self.plength = len(self.plist)*8 self.__fill() #填充 def __fill(self): #先填一个0x80(10000000) self.plist.append("0x80") #再填充0x00直到还剩8个字节(64) while (len(self.plist)+8)%64 != 0: self.plist.append("0x00") #用消息长度填满剩下的8个字节 p_len = hex(self.plength)[2:].rjust(16, "0") for i in range(0, len(p_len), 2): self.plist.append("0x" + p_len[i:i+2]) print(self.plist) #生成该组消息的80个32位子组 def genM80(self, z): #起始坐标 start = z*64 #把该组消息分成16个子组, 每组4个字节 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:])) #产生剩下的64个子组 for i in range(64): result.append(0) for i in range(16, 80, 1): result[i] = hex(L(int(result[i-3], 16)^int(result[i-8], 16)^int(result[i-14], 16)^int(result[i-16], 16), 1)) #对所有子组进行反转并返回 return result #对每轮进行加密 def fun(self, edcba_list, sfunc, w, k, n): for i in range(20): #计算出两个需要计算的结果并赋值给list[0]和list[3] xx = int(edcba_list[0], 16) + sfunc(int(edcba_list[3], 16), int(edcba_list[2], 16), int(edcba_list[1], 16)) + L(int(edcba_list[4], 16), 5) + int(w[20*n+i], 16) + int(k, 16) xx = hex(xx&0xffffffff) edcba_list[0] = xx edcba_list[3] = hex(L(int(edcba_list[3], 16), 30)) #把整个列表左移1位 x = edcba_list.pop(0) edcba_list.append(x) print(edcba_list) return edcba_list #加密函数 def encrypt(self): edcba_list = [E, D, C, B, A] for i in range(len(self.plist)//64): #保存寄存器初始值 EE, DD, CC, BB, AA = edcba_list #进行该组消息的4轮加密 #生成该组消息的80个子分组 w = self.genM80(i) print(w) #对每轮20步进行加密 edcba_list = self.fun(edcba_list, Ch, w, k1, 0) print("------------------------------------------") edcba_list = self.fun(edcba_list, Parity, w, k2, 1) print("------------------------------------------") edcba_list = self.fun(edcba_list, Maj, w, k3, 2) print("------------------------------------------") edcba_list = self.fun(edcba_list, Parity, w, k4, 3) print("------------------------------------------") output_e = hex((int(EE, 16) + int(edcba_list[0], 16))&0xffffffff) output_d = hex((int(DD, 16) + int(edcba_list[1], 16))&0xffffffff) output_c = hex((int(CC, 16) + int(edcba_list[2], 16))&0xffffffff) output_b = hex((int(BB, 16) + int(edcba_list[3], 16))&0xffffffff) output_a = hex((int(AA, 16) + int(edcba_list[4], 16))&0xffffffff) edcba_list = [output_e, output_d, output_c, output_b, output_a] edcba_list.reverse() abcde_list = edcba_list return abcde_list #显示结果 def show_result(self, abcde_list): result = "" for x in abcde_list: result += x[2:] return result if __name__ == "__main__": print("__________SHA1加密开始______________") fname = input("please enter the filename: ") #计时 start = clock() #读明文 f = open(fname, 'rb') plaintext = f.read() f.close() #加密 sha1 = SHA1(plaintext) ciphertext = sha1.show_result(sha1.encrypt()) #把密文写回文件 f = open(fname, 'w') f.write(ciphertext) f.close() print("______________加密结束______________") print("加密结果:%s" %ciphertext) print("加密时长: %.2f s" %(clock()-start))
转载地址:http://thaii.baihongyu.com/