⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha_1.cpp

📁 SHA1加密算法的VC++实现
💻 CPP
字号:
// SHA_1.cpp: implementation of the SHA_1 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SHA_1.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

struct Q
{
	char c[4];
}A,B,C,D,E,K[4],Y[16],W[80],H0,H1,H2,H3,H4;

// 字符二进制转换
void BinaryConversion(char szchar, char *pBinary);

// 循环左移iMove位32位字,iMove表示左移的位数,*pWord是待移的字
void LeftMove32(int iMove, char *pWord);

// c1+c2的模 32bit 加法(最高位不进位)
void mod32add(char *pchar1, char *pchar2, char *pWord);

// 计算W[i]的函数
void GetW(int i);

// f函数
struct Q Function(int t,Q b,Q c,Q d);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SHA_1::SHA_1()
{
}

SHA_1::~SHA_1()
{
}

// 字符二进制转换
void BinaryConversion(char szchar, char *pBinary)
{
	for (int i = 0; i < 8; i++)
	{
		if (( szchar & char(1)<<(8 - i) ) != 0) 
		{
			pBinary[i] = '1';
		}
		else 
		{
			pBinary[i] = '0';
		}
	}
	pBinary[8] = '\0';
}

// 循环左移iMove位32位字,iMove表示左移的位数,*pWord是待移的字
void LeftMove32(int iMove, char *pWord)
{
	int i = 0;
	int *p = new int[33];
	for(i = 0; i < 32; i++)
	{
		p[i] = (i + iMove) % 32 + 1;
	}
	p[32] = '\0';

	char *temp = new char[5];
	for (i = 0;i < 4; i++) 
	{
		temp[i]=char(0);     
	}
	temp[4] = '\0';

	for (i = 0; i < 32; i++)                        
	{
		int t1 = (p[i] - 1) / 8;
		int t2 = (p[i] - 1) % 8 + 1;                    
		int j = i % 8 + 1;
		if ((pWord[t1] & char(1) << (8 - t2)) != 0)   
		{
			temp[i / 8] = (temp[i / 8]) | (char(1)<<(8 - j));
		}
	}

	for (i = 0; i < 4; i++)
	{
		pWord[i] = temp[i];
	}

	delete temp;
	delete p;
}

// c1+c2的模 32bit 加法(最高位不进位)
void mod32add(char *pchar1, char *pchar2, char *pWord)
{
	//进位处理
	int bj = 0;  
	for (int i = 0;i < 4; i++)
	{
		pWord[i] = char(0);
	}

	i=0;
	while (i < 32)
	{
		int j = 8 - i % 8;
		int d1 = (pchar1[i / 8] & char(1) << (8 - j)); 
		int d2 = (pchar2[i / 8] & char(1) << (8 - j));
		int s = d1 + d2 + bj;
		if (s == 0) 
		{
			bj = 0;
		}
		else if (s == 1) 
		{ 
			bj = 0;
			pWord[i/8] = (pWord[i / 8]) | (char(1) << ( 8 - j));
		}
		else if (s==2) 
		{
			bj = 1;
		}
		else if (s==3) 
		{ 
			bj = 1;
			pWord[i / 8] = (pWord[i / 8]) | (char(1) << (8 - j));
		}
		i++;
	}
}

// 计算W[i]的函数
void GetW(int i)
{
	char c0,c1,c2,c3;
	c0 = W[i - 16].c[0] ^ W[i - 14].c[0] ^ W[i - 8].c[0] ^ W[i - 3].c[0];
	c1 = W[i - 16].c[1] ^ W[i - 14].c[1] ^ W[i - 8].c[1] ^ W[i - 3].c[1];
	c2 = W[i - 16].c[2] ^ W[i - 14].c[2] ^ W[i - 8].c[2] ^ W[i - 3].c[2];
	c3 = W[i - 16].c[3] ^ W[i - 14].c[3] ^ W[i - 8].c[3] ^ W[i - 3].c[3];
	W[i].c[0] = c0;  
	W[i].c[1] = c1;
	W[i].c[2] = c2;
	W[i].c[3] = c3;
	LeftMove32(1, W[i].c);
}

// f函数
struct Q Function(int t,Q b,Q c,Q d)
{
	struct Q temp;
	int i;
	if (t >= 0 && t <= 19) 
	{
		for (i = 0; i < 4; i++)
		{
            temp.c[i] = (b.c[i] & c.c[i]) | (~b.c[i] & d.c[i]);
		}
	}
    else if (t >= 20 && t <= 39)
	{
        for (i = 0; i < 4; i++)
		{
			temp.c[i] = b.c[i] ^ c.c[i] ^ d.c[i];
		}
	}
	else if (t >= 40 && t <= 59)
	{
		for (i = 0;i < 4; i++)
		{
			temp.c[i] = (b.c[i] & c.c[i]) | (b.c[i] & d.c[i]) | (c.c[i] & d.c[i]);
		}
	}
	else
	{
		for (i = 0; i < 4; i++)
		{
			temp.c[i] = b.c[i] ^ c.c[i] ^ d.c[i];
		}
	}
	return temp;
}

// SHA_1算法核心部分,计算消息摘要, strMessage为消息
CString SHA_1::SHA_1Arithmetic(CString strMessage)
{
	//=========初始化缓冲区A,B,C,D,E========
   	A.c[0] = char(0x67);  A.c[1] = char(0x45);  A.c[2] = char(0x23);  A.c[3] = char(0x01);
   	B.c[0] = char(0xEF);  B.c[1] = char(0xCD);  B.c[2] = char(0xAB);  B.c[3] = char(0x89);
    C.c[0] = char(0x98);  C.c[1] = char(0xBA);  C.c[2] = char(0xDC);  C.c[3] = char(0xFE);
    D.c[0] = char(0x10);  D.c[1] = char(0x32);  D.c[2] = char(0x54);  D.c[3] = char(0x76);
   	E.c[0] = char(0xC3);  E.c[1] = char(0xD2);  E.c[2] = char(0xE1);  E.c[3] = char(0xF0);
	
	int i;

	// 给H0,H1,H2,H3,H4负初值
    for(i = 0;i < 4; i++)
	{
		H0.c[i] = A.c[i];
		H1.c[i] = B.c[i];
		H2.c[i] = C.c[i];
		H3.c[i] = D.c[i];
		H4.c[i] = E.c[i];
	}

	for (i = 0; i < 16; i++)
	{
		Y[i].c[0] = char(0);	
		Y[i].c[1] = char(0);
		Y[i].c[2] = char(0);	
		Y[i].c[3] = char(0);
	}

	int len = strMessage.GetLength();

	// 对消息进行补位补长操作 
	int addlength = 0;
	addlength = 448 - (len * 8) % 512; 

	// addlength 的目的是直接将消息补成512的倍数
	if (addlength <= 0) 
	{
		addlength += 512;
	}
	int L = (len * 8 + addlength + 64) / 8 + 1;
	char *MessageAddLong = new char[L];
	for (i = 0; i < L; i++) 
	{
		MessageAddLong[i]='\0';
	}
	for (i = 0; i < len; i++)
	{
		MessageAddLong[i] = strMessage.GetAt(i);
	}
	MessageAddLong[len] = char(-128);

	for (i = len + 1; i < L - 1; i++) 
	{
		MessageAddLong[i] = '\0';
	}
	MessageAddLong[L-1] = '\0';

	// 求len的二进制
	int temp = len;
	int s = 1;
	int r[64];
	while(temp != 1)
	{
	 r[s++] = temp % 2;
	 temp /= 2;
	}
	r[s] = 1;             
	r[s + 1] = -1;
	
	 // 附加长度值
	for (i = 1;i <= s; i++)
	{
		if (r[i])
		{
			MessageAddLong[L - 2 - (i - 1) / 8] = MessageAddLong[L - 2 - (i - 1) / 8] | (char(1) << ((i - 1) % 8));  
		}
	}

	struct Q temp1, temp2, temp3, temp4;
	int t = 0;
	int length = 0;

	//=======计算A,B,C,D,E==============
	while(length < (L - 1))
	{ 
		for (i = 0;i < 16; i++)
		{
			for (int j = 0;j < 4; j++)
			{
				Y[i].c[j] = W[i].c[j] = MessageAddLong[length++];
			}
		}
		for (i = 16;i < 80; i++)
		{
			GetW(i);
		}
		for (t=0;t<80;t++)
		{
			temp1 = A;   

			// 处理S5(A)
		    LeftMove32(5, temp1.c); 

		    temp2 = B;

			// 处理S30(B)
		    LeftMove32(30, temp2.c);

			temp3 = Function(t,B,C,D);
		    for (i=0;i<4;i++)
			{
		    	temp4.c[i] = E.c[i] ^ temp3.c[i] ^ temp1.c[i] ^ W[t].c[i] ^K[t / 20].c[i];
			}
			A = temp4; 
			B = A; 
			C = temp2; 
			D = C;  
			E = D;
		}
		mod32add(A.c, A.c, H0.c);
		mod32add(B.c, B.c, H1.c);
		mod32add(C.c, C.c, H2.c);
		mod32add(D.c, D.c, H3.c);
		mod32add(E.c, E.c, H4.c);
	}

	// Message_Digest是未转化成二进制的消息摘要
	char *Message_Digest = new char[21];
	for (i = 0; i < 4; i++)
	{  
		Message_Digest[i] = A.c[i];
		Message_Digest[i+4] = B.c[i];
		Message_Digest[i+8] = C.c[i];
		Message_Digest[i+12] = D.c[i];
		Message_Digest[i+16] = E.c[i];
	}
   	Message_Digest[20]='\0';  

	// 以2进制的形式显示消息摘要
	CString strMessageDigest = "";
	for (i = 0;i < 20; i++)
	{
		char szBinary[9];
		BinaryConversion(Message_Digest[i], szBinary);
		strMessageDigest += szBinary;
	}

	delete Message_Digest;
	delete MessageAddLong;

	// 返回消息摘要
	return strMessageDigest;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -