zoukankan      html  css  js  c++  java
  • 加密散列算法——SHA-1

    与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;
    }


    详细C++实现算法下载


  • 相关阅读:
    Python_Tips[3] -> sort/sorted 排序函数
    Python_Tips[2] -> 函数延后估值及字节码分析
    Python_Tips[1] -> 利用 Python 的字典实现 Switch 功能
    Python_Tips[0] -> 关于 import
    Python与数据库[2] -> 关系对象映射/ORM[4] -> sqlalchemy 的显式 ORM 访问方式
    Python与数据库[2] -> 关系对象映射/ORM[3] -> sqlalchemy 的声明层 ORM 访问方式
    Python与数据库[2] -> 关系对象映射/ORM[2] -> 建立声明层表对象的两种方式
    JS实现网页选取截屏 保存+打印 功能(转)
    nodejs+koa2 实现一个get请求
    windwos下安装使用nginx(转)
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7209723.html
Copyright © 2011-2022 走看看