密码加密解密(八)——SHA散列算法实现

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值