【题目】

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"

#Kr
k1 = "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   #第四轮函数也是Parity
Maj = lambda x, y, z: (x&y)^(x&z)^(y&z)

#左移n位
L = lambda x,n:(((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))
    
        
            
            
            
        
        
        



Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐