与MD5算法类似,SHA-1算法也是在接收到消息后产生消息摘要,能够用来验证数据的完整性。
不同的是SHA1会产生一个160位的消息摘要(MD5产生的是128位)。
其它的性质之类的不多说(请參考前面MD5算法),直接上SHA-1算法的步骤
1、补位
首先要进行补位,使得补位后信息的长度对512求余为448。
即数据扩展至
K*512+448(bit),即K*64+56(byte)。K为自然数。
详细补位操作:先补一个1。后面补0至满足上述要求。最少要补1bit,最多补512bit。
2、补长度
在K*64+56(byte)的基础上补上8byte,这8byte是用来保存原始信息的长度。
3、使用的常量
一系列的常量字K(0), K(1), ... , K(79),假设以16进制给出。
它们例如以下:
Kt = 0x5A827999 (0 <= t <= 19)
Kt = 0x6ED9EBA1 (20 <= t <= 39)
Kt = 0x8F1BBCDC (40 <= t <= 59)
Kt = 0xCA62C1D6 (60 <= t <= 79)
初始化缓冲常量
H0 = 67452301
H1 = EFCDAB89
H2 = 98BADCFE
H3 = 10325476
H4 = C3D2E1F0
4、辅助函数与加密函数
首先定义4个辅助函数:
(0<=t<20):f(B,C,D,t)=(B & C) | ((~B) & D);
(20<=t<40):f(B,C,D,t)=B ^ C ^ D;
(40<=t<60):f(B,C,D,t)=(B & C) | ((B & D) | (C & D));
(60<=t<80):f(B,C,D,t)=B ^ C ^ D;
C++代码例如以下
#include <iostream> #include <iomanip> #include <string> #include <sstream> using namespace std; unsigned circleShift(const unsigned& word,const int& bits){ return (word<<bits) | ((word)>>(32-bits)); } unsigned sha1Fun(const unsigned& B,const unsigned& C,const unsigned& D,const unsigned& t){ switch (t/20){ case 0: return (B & C) | ((~B) & D); case 2: return (B & C) | (B & D) | (C & D); case 1: case 3: return B ^ C ^ D; } return t; } string sha1(const string& strRaw){ string str(strRaw); str+=(unsigned char)(0x80); // 每一个字节8位,所以要乘8,左移3位 while (str.size()<<3 % 512 != 448){ str+=(char)0; } // 写入原始数据长度 for (int i(56);i>=0;i-=8){ str+=(unsigned char)((((unsigned __int64)strRaw.size())<<3) >> i); } const unsigned K[4]={0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6}; unsigned A(0x67452301),B(0xefcdab89),C(0x98badcfe),D(0x10325476),E(0xc3d2e1f0),T(0); unsigned W[80]={0}; // 每次处理64字节,共512位 for (unsigned i(0);i!=str.size();i+=64){ // 前16个字为原始数据 for (unsigned t(0);t!=16;++t){ // 将4个8位数据放入一个32位变量中 W[t]=((unsigned)str[i+4*t] & 0xff)<<24 | ((unsigned)str[i+4*t+1] & 0xff)<<16 | ((unsigned)str[i+4*t+2] & 0xff)<<8 | ((unsigned)str[i+4*t+3] & 0xff); } // 填充 for (unsigned t(16);t!=80;++t){ W[t]=circleShift(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16],1); } for (unsigned t(0);t!=80;++t){ T=circleShift(A,5) + sha1Fun(B,C,D,t) + E + W[t] + K[t/20]; E=D; D=C; C=circleShift(B,30); B=A; A=T; } A+=0x67452301; B+=0xefcdab89; C+=0x98badcfe; D+=0x10325476; E+=0xc3d2e1f0; } stringstream ss; ss<<setw(8)<<setfill('0')<<hex<<A<<B<<C<<D<<E; ss>>str; return str; } int main(int argc,char *argv[]){ string str(""); cout<<"in put a string :"<<endl; getline(cin,str); cout<<"raw string: "<<str<<endl <<"sha1 encode: "<<sha1(str)<<endl; system("pause"); return 0; }