SHA-256算法
算法简介
- 对于长度小于2^64位的消息,SHA256会产生一个160位的消息摘要。
- 当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。
- 在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
- 是对SHA1函数的扩展
功能实现
全部代码
"""
File Name: SHA-256算法.py
Program IDE: PyCharm
Create Time: 2021-10-04 14:13
Create By Author: 陆依依
"""
import hashlib
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):
c = c + chr(int(b[i: i+8], 2))
message = message + chr(128) + chr(0) * int(k / 8) + c
return message
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)
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 = H7
for 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', ''))
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.sha256(message).hexdigest())
print('hash是否相等?\t' + str(hashlib.sha256(message).hexdigest() == Encrypt(message)))
实验结果