hash算法|SHA-256哈希函数实现


文章目录

  • SHA-256算法
    • 算法简介
    • 功能实现
    • 全部代码
    • 实验结果

SHA-256算法 算法简介
  • 对于长度小于2^64位的消息,SHA256会产生一个160位的消息摘要。
  • 当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。
  • 在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
  • 是对SHA1函数的扩展
功能实现
  • 加密文件
  • 加密字符串
  • 检验哈希值
全部代码
# -*-coding:utf-8-*- """ File Name: SHA-256算法.pyProgram IDE: PyCharmCreate Time: 2021-10-04 14:13Create 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# 循环右移t位 def ROTR(t, num): temp = (32 - len(bin(num).replace('0b', ''))) * '0' + bin(num).replace('0b', '') return int(temp[32-t:] + temp[:32-t], 2)# 右移t位 def SHR(t, num): temp = (32 - len(bin(num).replace('0b', ''))) * '0' + bin(num).replace('0b', '') return int(temp[:32-t], 2)# 逻辑函数 def FF(t, x, y=0, z=0): if t == 1: return (x & y) ^ (~x & z) elif t == 2: return (x & y) ^ (x & z) ^ (y & z) elif t == 3: return ROTR(2, x) ^ ROTR(13, x) ^ ROTR(22, x) elif t == 4: return ROTR(6, x) ^ ROTR(11, x) ^ ROTR(25, x) elif t == 5: return ROTR(7, x) ^ ROTR(18, x) ^ SHR(3, x) elif t == 6: return ROTR(17, x) ^ ROTR(19, x) ^ SHR(10, x)# 加密 def Encrypt(message): message = Padding(message)# 初始化变量 H0 = int('6A09E667', 16) H1 = int('BB67AE85', 16) H2 = int('3C6EF372', 16) H3 = int('A54FF53A', 16) H4 = int('510E527F', 16) H5 = int('9B05688C', 16) H6 = int('1F83D9AB', 16) H7 = int('5BE0CD19', 16)# 常量 K = [int('428a2f98', 16), int('71374491', 16), int('b5c0fbcf', 16), int('e9b5dba5', 16), int('3956c25b', 16), int('59f111f1', 16), int('923f82a4', 16), int('ab1c5ed5', 16), int('d807aa98', 16), int('12835b01', 16), int('243185be', 16), int('550c7dc3', 16), int('72be5d74', 16), int('80deb1fe', 16), int('9bdc06a7', 16), int('c19bf174', 16), int('e49b69c1', 16), int('efbe4786', 16), int('0fc19dc6', 16), int('240ca1cc', 16), int('2de92c6f', 16), int('4a7484aa', 16), int('5cb0a9dc', 16), int('76f988da', 16), int('983e5152', 16), int('a831c66d', 16), int('b00327c8', 16), int('bf597fc7', 16), int('c6e00bf3', 16), int('d5a79147', 16), int('06ca6351', 16), int('14292967', 16), int('27b70a85', 16), int('2e1b2138', 16), int('4d2c6dfc', 16), int('53380d13', 16), int('650a7354', 16), int('766a0abb', 16), int('81c2c92e', 16), int('92722c85', 16), int('a2bfe8a1', 16), int('a81a664b', 16), int('c24b8b70', 16), int('c76c51a3', 16), int('d192e819', 16), int('d6990624', 16), int('f40e3585', 16), int('106aa070', 16), int('19a4c116', 16), int('1e376c08', 16), int('2748774c', 16), int('34b0bcb5', 16), int('391c0cb3', 16), int('4ed8aa4a', 16), int('5b9cca4f', 16), int('682e6ff3', 16), int('748f82ee', 16), int('78a5636f', 16), int('84c87814', 16), int('8cc70208', 16), int('90befffa', 16), int('a4506ceb', 16), int('bef9a3f7', 16), int('c67178f2', 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, 64): W.append((FF(6, W[j-2]) + W[j-7] + FF(5, W[j-15]) + W[j-16]) % (2**32))# 寄存器 A = H0 B = H1 C = H2 D = H3 E = H4 F = H5 G = H6 H = H7for j in range(0, 64): T1 = (H + FF(4, E) + FF(1, E, F, G) + K[j] + W[j]) % (2**32) T2 = (FF(3, A) + FF(2, A, B, C)) % (2**32) H = G G = F F = E E = (D + T1) % (2**32) D = C C = B B = A A = (T1 + T2) % (2**32)H0 = (H0 + A) % (2**32) H1 = (H1 + B) % (2**32) H2 = (H2 + C) % (2**32) H3 = (H3 + D) % (2**32) H4 = (H4 + E) % (2**32) H5 = (H5 + F) % (2**32) H6 = (H6 + G) % (2**32) H7 = (H7 + H) % (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', '') + (8 - len(str(hex(H5)).replace('0x', ''))) * '0' + str(hex(H5)).replace('0x', '') + (8 - len(str(hex(H6)).replace('0x', ''))) * '0' + str(hex(H6)).replace('0x', '') + (8 - len(str(hex(H7)).replace('0x', ''))) * '0' + str(hex(H7)).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 = tempprint('手动实现:' + Encrypt(message)) print('调库检验:' + hashlib.sha256(message).hexdigest()) print('hash是否相等?\t' + str(hashlib.sha256(message).hexdigest() == Encrypt(message)))

实验结果 【hash算法|SHA-256哈希函数实现】hash算法|SHA-256哈希函数实现
文章图片

    推荐阅读