SHA1实现
明文填充
对输入的字符串进行填充,首先在明文后面接上一比特的1,然后再添加若干个0使得总长度模512同余448,最后再添加64比特,其数值表示的是明文的长度。
因为输入的都是字符串,一个字符8个bit,我们首先可以算得:明文的比特数=字符数*8。从而可以计算出需要填充的0的个数为(447-明文比特数)%512
sha1面向字进行操作,因此我们可以创建一个关于字的vector作为返回结果。首先对于字符串,每4个字符为一个字,先将它们push进vector。然后讨论字符串剩余1,2,3个字符的情况,分别在其后面添加一个比特1和若干比特0,使得长度为32比特,作为一个字push进vector。接着,计算剩下还要push多少个字的0,把它们push进vector。最后分两个字来push那个表示明文原长度的64比特即可。
F函数
F函数读取B,C,D以及t的值作为输入,并根据t的不同值对BCD进行不同的运算并返回运算结果。实现的时候B,C,D都是bitset<32>,因此可以直接进行相对应的位运算。
1 | Word F_function(Word B, Word C, Word D,int t){ |
加密算法
由于bitset没有内置的模2^32加法的功能,因此实现了一个add函数用于作模2^32加法操作。
设置全局变量H0,H1,H2,H3,H4和K数组,数值按照书上给出的来。
首先,对明文进行填充,填充的结果是一个关于字的vector,记为Y。由于512bit为一组,也就是16个字,计算n=Y.size()/16。进行n次的for循环,在每次循环中做如下操作:
- 计算W数组
- 通过一系列运算,更新H0,H1,H2,H3,H4的值
书上给出了伪代码,实现成c++具体的操作如下:
1 | for(int i = 0; i < n; i++){ |
循环进行完之后,输出H0||H1||H2||H3||H4的指即为所求得的哈希值
main函数
从plaintext.txt中读入内容,这里读入的最长为8192字节,即最大可读入8k的文件。将读入内容构造成字符串,传入加密函数中进行加密。