Copyright © 2018 Joyce_BY
All rights reserved.
Contact by Yagnes126@gmail.com
实验原理
SHA-1接受一串二进制输入,加密后得到160bit的消息摘要,是一种hash加密。
算法的主要过程如下:
- 接收一串比特流,对其进行如下扩展:
- 在比特流尾部添加一个‘1’;
- 在新的比特流的尾部添加[0,512)个‘0’,使得最终bit数congruent to 448(mod 512);
- 最后在比特流尾部添加上64-bit的原消息长度。
- 初始化数值如下:
h = [0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0]
k = [0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6]
- 把扩展后的bit stream以每512bit分组作为一个chunk,对每个chunk进行如下操作:
a) 把此chunk分成16个32bit的word;
b) 将16个word扩展到80个word,如下:
word = leftrotate(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16],1)
c) 初始化a,b,c,d,e,分别等于h[0] - h[4];
d) 对word[i]做如下操作:
根据i算出f;
f = (b and c) or ((not b) and d), 0 ≤ i ≤ 19
f = b xor c xor d, 20 ≤ i ≤ 39
f = (b and c) or (b and d) or (c and d), 40 ≤ i ≤ 59
f = b xor c xor d, 60 ≤ i ≤ 79
算出新的a,b,c,d,e的值:
temp = (a leftrotate 5) + f + e + k[i/20] + w[i]
e = d,d = c,c = b leftrotate 30,b = a,a = temp
将新的a,b,c,d,e的值对应加到h[0]-h[4]得到新的h,作为下一个chunk的初始hash值。
- 最终将得到的h[0]-h[4]连接起来就是160bit的消息摘要。
hh = (h[0] << 128) | (h[1] << 96) | (h[2] << 64) | (h[3] << 32) | h[4]
主要算法
- 消息预处理
得到最初的消息长度;
把传入的str类型变量转换成字节存储在一个list中;
添加1,因为基于字节操作,也就是添加0x80;
加0直到list的长度在模64下与与-8同余;
将原始长度以8字节添加到末尾;
每64个字节为一个chunk,将其分为一个list;
最终返回一个含有n个列表,每个列表含64个字节的列表。
CODE
def preprocess(ss):
ml = len(ss)*8
li = []
for ch in ss:
li.append(ord(ch))
li.append(0x80)
if len(li) % 64 < 56:
li.extend([0]*(56 - len(li) % 64))
li.extend([0,