SHA-1散列算法实现

SHA-1算法

算法简介

  • 对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。
  • 当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。
  • 在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
  • SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要,(但会有1x10 ^ 48分之一的机率出现相同的消息摘要,一般使用时忽略)。
  • 详细步骤参见FISP-180-2标准

功能实现

  • 加密文件
  • 加密字符串
  • 检验hash值

全部代码

# -*-coding:utf-8-*-
"""
File Name: SHA-1算法.py

Program IDE: PyCharm

Create Time: 2021-09-18 20:15

Create By Author: 陆依依

"""

import hashlib			# 为了调库检验


# 字符串转为2进制
def Encode(string):
    return ''.join([(8 - len(bin(ord(s)).replace('0b', ''))) * '0' + bin(ord(s)).replace('0b', '') for s in string])


# 填充消息
def Padding(message):
    # 将字节转为字符
    message = ''.join([chr(message[i]) for i in range(len(message))])
    l = len(message) * 8 % 512
    if l + 1 > 448:
        k = 512 - (l + 1 - 448)
    else:
        k = 448 - l - 1
    a = bin(len(message) * 8).replace('0b', '')
    b = '0' * (64 - len(a)) + a
    c = ''
    for i in range(0, 64, 8):           # 后64bit
        c = c + chr(int(b[i: i+8], 2))
    message = message + chr(128) + chr(0) * int(k / 8) + c
    return message


# 逻辑函数
def F(t, B, C, D):
    if t <= 19:
        return (B & C) | (~B & D)
    elif t <= 39:
        return B ^ C ^ D
    elif t <= 59:
        return (B & C) | (B & D) | (C & D)
    else:
        return B ^ C ^ D


# 将数字num循环左移t位
def ROTL(t, num):
    temp = (32 - len(bin(num).replace('0b', ''))) * '0' + bin(num).replace('0b', '')
    return int(temp[t:] + temp[:t], 2)


# 加密
def Encrypt(message):
    message = Padding(message)
    # 初始化变量
    H0 = int('67452301', 16)
    H1 = int('EFCDAB89', 16)
    H2 = int('98BADCFE', 16)
    H3 = int('10325476', 16)
    H4 = int('C3D2E1F0', 16)

    # 常量
    K = [int('5A827999', 16), int('6ED9EBA1', 16), int('8F1BBCDC', 16), int('CA62C1D6', 16)]

    # 分块处理
    for i in range(0, len(message), 64):
        temp = Encode(message[i:i + 64])
        W = [int(temp[j:j + 32], 2) for j in range(0, 512, 32)]
        for j in range(16, 80):
            W.append(ROTL(1, (W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16])))
        A = H0
        B = H1
        C = H2
        D = H3
        E = H4
        for j in range(0, 80):
            T = (ROTL(5, A) + F(j, B, C, D) + E + W[j] + K[int(j / 20)]) % (2 ** 32)
            E = D
            D = C
            C = ROTL(30, B)
            B = A
            A = T
        H0 = (A + H0) % (2 ** 32)
        H1 = (B + H1) % (2 ** 32)
        H2 = (C + H2) % (2 ** 32)
        H3 = (D + H3) % (2 ** 32)
        H4 = (E + H4) % (2 ** 32)
    return str((8-len(str(hex(H0)).replace('0x', ''))) * '0' + str(hex(H0)).replace('0x', '') +
    (8 - len(str(hex(H1)).replace('0x', ''))) * '0' + str(hex(H1)).replace('0x', '') +
    (8 - len(str(hex(H2)).replace('0x', ''))) * '0' + str(hex(H2)).replace('0x', '') +
    (8 - len(str(hex(H3)).replace('0x', ''))) * '0' + str(hex(H3)).replace('0x', '') +
    (8 - len(str(hex(H4)).replace('0x', ''))) * '0' + str(hex(H4)).replace('0x', ''))


# demo
if __name__ == "__main__":
    while(True):
        path = ''     # 默认文件路径
        choose = int(input('请选择加密对象:1)文件  2)非文件\t'))
        if choose == 2:
            message = input('请输入待加密内容:').encode('utf-8')
        else:
            path = input('请输入完整文件路径:')
            message = open(path, 'rb').readlines()
            temp = message[0]
            for i in range(1, len(message)):
                temp = temp + message[i]
            message = temp

        print('手动实现:' + Encrypt(message))
        print('调库检验:' + hashlib.sha1(message).hexdigest())
        print('hash是否相等?\t' + str(hashlib.sha1(message).hexdigest() == Encrypt(message)))
        

实验结果

运行结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值