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

📄 sha.cpp

📁 实现多种加解密算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:

//SHA.cpp
#include "stdafx.h"
#include "SHA.h"

#include <exception>
#include <strstream>

using namespace std;

const unsigned int CSHA::sm_K160[4] =
{
	0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
};

const unsigned int CSHA::sm_H160[SHA160LENGTH] =
{
	0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
};

const unsigned int CSHA::sm_K256[64] =
{
	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 
};

const unsigned int CSHA::sm_H256[SHA256LENGTH] =
{
	0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
	0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};

const SUI64 CSHA::sm_H384[SHA512LENGTH] =
{
	{0xcbbb9d5d, 0xc1059ed8},
	{0x629a292a, 0x367cd507},
	{0x9159015a, 0x3070dd17},
	{0x152fecd8, 0xf70e5939},
	{0x67332667, 0xffc00b31},
	{0x8eb44a87, 0x68581511},
	{0xdb0c2e0d, 0x64f98fa7},
	{0x47b5481d, 0xbefa4fa4}
};

const SUI64 CSHA::sm_K512[80] =
{
	{0x428a2f98, 0xd728ae22}, {0x71374491, 0x23ef65cd},
	{0xb5c0fbcf, 0xec4d3b2f}, {0xe9b5dba5, 0x8189dbbc},
	{0x3956c25b, 0xf348b538}, {0x59f111f1, 0xb605d019},
	{0x923f82a4, 0xaf194f9b}, {0xab1c5ed5, 0xda6d8118},
	{0xd807aa98, 0xa3030242}, {0x12835b01, 0x45706fbe},
	{0x243185be, 0x4ee4b28c}, {0x550c7dc3, 0xd5ffb4e2},
	{0x72be5d74, 0xf27b896f}, {0x80deb1fe, 0x3b1696b1},
	{0x9bdc06a7, 0x25c71235}, {0xc19bf174, 0xcf692694},
	{0xe49b69c1, 0x9ef14ad2}, {0xefbe4786, 0x384f25e3},
	{0x0fc19dc6, 0x8b8cd5b5}, {0x240ca1cc, 0x77ac9c65},
	{0x2de92c6f, 0x592b0275}, {0x4a7484aa, 0x6ea6e483},
	{0x5cb0a9dc, 0xbd41fbd4}, {0x76f988da, 0x831153b5},
	{0x983e5152, 0xee66dfab}, {0xa831c66d, 0x2db43210},
	{0xb00327c8, 0x98fb213f}, {0xbf597fc7, 0xbeef0ee4},
	{0xc6e00bf3, 0x3da88fc2}, {0xd5a79147, 0x930aa725},
	{0x06ca6351, 0xe003826f}, {0x14292967, 0x0a0e6e70},
	{0x27b70a85, 0x46d22ffc}, {0x2e1b2138, 0x5c26c926},
	{0x4d2c6dfc, 0x5ac42aed}, {0x53380d13, 0x9d95b3df},
	{0x650a7354, 0x8baf63de}, {0x766a0abb, 0x3c77b2a8},
	{0x81c2c92e, 0x47edaee6}, {0x92722c85, 0x1482353b},
	{0xa2bfe8a1, 0x4cf10364}, {0xa81a664b, 0xbc423001},
	{0xc24b8b70, 0xd0f89791}, {0xc76c51a3, 0x0654be30},
	{0xd192e819, 0xd6ef5218}, {0xd6990624, 0x5565a910},
	{0xf40e3585, 0x5771202a}, {0x106aa070, 0x32bbd1b8},
	{0x19a4c116, 0xb8d2d0c8}, {0x1e376c08, 0x5141ab53},
	{0x2748774c, 0xdf8eeb99}, {0x34b0bcb5, 0xe19b48a8},
	{0x391c0cb3, 0xc5c95a63}, {0x4ed8aa4a, 0xe3418acb},
	{0x5b9cca4f, 0x7763e373}, {0x682e6ff3, 0xd6b2b8a3},
	{0x748f82ee, 0x5defb2fc}, {0x78a5636f, 0x43172f60},
	{0x84c87814, 0xa1f0ab72}, {0x8cc70208, 0x1a6439ec},
	{0x90befffa, 0x23631e28}, {0xa4506ceb, 0xde82bde9},
	{0xbef9a3f7, 0xb2c67915}, {0xc67178f2, 0xe372532b},
	{0xca273ece, 0xea26619c}, {0xd186b8c7, 0x21c0c207},
	{0xeada7dd6, 0xcde0eb1e}, {0xf57d4f7f, 0xee6ed178},
	{0x06f067aa, 0x72176fba}, {0x0a637dc5, 0xa2c898a6},
	{0x113f9804, 0xbef90dae}, {0x1b710b35, 0x131c471b},
	{0x28db77f5, 0x23047d84}, {0x32caab7b, 0x40c72493},
	{0x3c9ebe0a, 0x15c9bebc}, {0x431d67c4, 0x9c100d4c},
	{0x4cc5d4be, 0xcb3e42b6}, {0x597f299c, 0xfc657e2a},
	{0x5fcb6fab, 0x3ad6faec}, {0x6c44198c, 0x4a475817}
};

const SUI64 CSHA::sm_H512[SHA512LENGTH] =
{
	{0x6a09e667, 0xf3bcc908},
	{0xbb67ae85, 0x84caa73b},
	{0x3c6ef372, 0xfe94f82b},
	{0xa54ff53a, 0x5f1d36f1},
	{0x510e527f, 0xade682d1},
	{0x9b05688c, 0x2b3e6c1f},
	{0x1f83d9ab, 0xfb41bd6b},
	{0x5be0cd19, 0x137e2179}
};

//CONSTRUCTOR
CSHA::CSHA(int iMethod)
{
	//Check the method
	switch(iMethod)
	{
		case SHA160:
			{
				for(int i=0; i<SHA160LENGTH; i++)
					m_auiBuf[i] = sm_H160[i];
				m_auiBits[0] = 0;
				m_auiBits[1] = 0;
			}
			break;

		case SHA256:
			{
				for(int i=0; i<SHA256LENGTH; i++)
					m_auiBuf[i] = sm_H256[i];
				m_auiBits[0] = 0;
				m_auiBits[1] = 0;
			}
			break;

		case SHA384:
			{
				for(int i=0; i<SHA512LENGTH; i++)
					m_aoui64Buf[i] = sm_H384[i];
				m_aoui64Bits[0].m_uiLeft = 0;
				m_aoui64Bits[0].m_uiRight = 0;
				m_aoui64Bits[1].m_uiLeft = 0;
				m_aoui64Bits[1].m_uiRight = 0;
			}
			break;

		case SHA512:
			{
				for(int i=0; i<SHA512LENGTH; i++)
					m_aoui64Buf[i] = sm_H512[i];
				m_aoui64Bits[0].m_uiLeft = 0;
				m_aoui64Bits[0].m_uiRight = 0;
				m_aoui64Bits[1].m_uiLeft = 0;
				m_aoui64Bits[1].m_uiRight = 0;
			}
			break;

		default:
		{
			ostrstream ostr;
			ostr << "FileDigest ERROR: in CSHA() Constructor, Illegal Method " << iMethod << "!" << ends;
			string ostrMsg = ostr.str();
			ostr.freeze(false);
			throw runtime_error(ostrMsg);
		}
	}
	m_iMethod = iMethod;
}

//Update context to reflect the concatenation of another buffer of bytes.
void CSHA::AddData(char const* pcData, int iDataLength)
{
	if(iDataLength < 0)
		throw runtime_error(string("FileDigest ERROR: in CSHA::AddData(), Data Length should be >= 0!"));
	unsigned int uiT;
	switch(m_iMethod)
	{
		case SHA160:
		case SHA256:
			{
				//Update bitcount
				uiT = m_auiBits[0];
				if((m_auiBits[0] = uiT + ((unsigned int)iDataLength << 3)) < uiT)
					m_auiBits[1]++; //Carry from low to high
				m_auiBits[1] += iDataLength >> 29;
				uiT = (uiT >> 3) & (BLOCKSIZE-1); //Bytes already
				//Handle any leading odd-sized chunks
				if(uiT != 0)
				{
					unsigned char* puc = (unsigned char*)m_aucIn + uiT;
					uiT = BLOCKSIZE - uiT;
					if(iDataLength < uiT)
					{
						memcpy(puc, pcData, iDataLength);
						return;
					}
					memcpy(puc, pcData, uiT);
					Transform();
					pcData += uiT;
					iDataLength -= uiT;
				}
				//Process data in 64-byte chunks
				while(iDataLength >= BLOCKSIZE)
				{
					memcpy(m_aucIn, pcData, BLOCKSIZE);
					Transform();
					pcData += BLOCKSIZE;
					iDataLength -= BLOCKSIZE;
				}
				//Handle any remaining bytes of data
				memcpy(m_aucIn, pcData, iDataLength);
			}
			break;

		case SHA384:
		case SHA512:
			{
				uiT = m_aoui64Bits[0].m_uiRight;
				unsigned int uiU = m_aoui64Bits[0].m_uiLeft;
				if((m_aoui64Bits[0].m_uiRight = uiT + ((unsigned int)iDataLength << 3)) < uiT)
					m_aoui64Bits[0].m_uiLeft++; //Carry from low to high
				unsigned int uiV = m_aoui64Bits[1].m_uiRight;
				if((m_aoui64Bits[0].m_uiLeft += iDataLength >> 29) < uiU)
					m_aoui64Bits[1].m_uiRight++;
				if(m_aoui64Bits[1].m_uiRight < uiV)
					m_aoui64Bits[1].m_uiLeft++;
				uiT = (uiT >> 3) & (BLOCKSIZE2-1); //Bytes already
				//Handle any leading odd-sized chunks
				if(uiT != 0)
				{
					unsigned char* puc = (unsigned char*)m_aucIn + uiT;
					uiT = BLOCKSIZE2 - uiT;
					if(iDataLength < uiT)
					{
						memcpy(puc, pcData, iDataLength);
						return;
					}
					memcpy(puc, pcData, uiT);
					Transform();
					pcData += uiT;
					iDataLength -= uiT;
				}
				//Process data in 64-byte chunks
				while(iDataLength >= BLOCKSIZE2)
				{
					memcpy(m_aucIn, pcData, BLOCKSIZE2);
					Transform();
					pcData += BLOCKSIZE2;
					iDataLength -= BLOCKSIZE2;
				}
				//Handle any remaining bytes of data
				memcpy(m_aucIn, pcData, iDataLength);
			}
			break;
	}
	//Set the flag
	m_bAddData = true;
}

//Final wrapup - pad to 64-byte boundary with the bit pattern 
//1 0*(64-bit count of bits processed, MSB-first)
void CSHA::FinalDigest(char* pcDigest)
{
	//Is the User's responsability to ensure that pcDigest is properly allocated 20, 32,
	//48 or 64 bytes, depending on the method
	if(false == m_bAddData)
		throw runtime_error(string("FileDigest ERROR: in CSHA::FinalDigest(), No data Added before call!"));
	switch(m_iMethod)
	{
		case SHA160:
		case SHA256:
			{
				unsigned int uiCount;
				unsigned char *puc;
				//Compute number of bytes mod 64
				uiCount = (m_auiBits[0] >> 3) & (BLOCKSIZE-1);
				//Set the first char of padding to 0x80. This is safe since there is
				//always at least one byte free
				puc = m_aucIn + uiCount;
				*puc++ = 0x80;
				//Bytes of padding needed to make 64 bytes
				uiCount = BLOCKSIZE - uiCount - 1;
				//Pad out to 56 mod 64
				if(uiCount < 8)
				{
					//Two lots of padding: Pad the first block to 64 bytes
					memset(puc, 0, uiCount);
					Transform();
					//Now fill the next block with 56 bytes
					memset(m_aucIn, 0, BLOCKSIZE-8);
				}
				else
				{
					//Pad block to 56 bytes
					memset(puc, 0, uiCount - 8);
				}
				//Append length in bits and transform
				Word2Bytes(m_auiBits[1], &m_aucIn[BLOCKSIZE-8]);
				Word2Bytes(m_auiBits[0], &m_aucIn[BLOCKSIZE-4]);
				Transform();
				switch(m_iMethod)
				{
					case SHA160:
						{
							for(int i=0; i<SHA160LENGTH; i++,pcDigest+=4)
								Word2Bytes(m_auiBuf[i], reinterpret_cast<unsigned char*>(pcDigest));
						}
						break;

					case SHA256:
						{
							for(int i=0; i<SHA256LENGTH; i++,pcDigest+=4)
								Word2Bytes(m_auiBuf[i], reinterpret_cast<unsigned char*>(pcDigest));
						}
						break;
				}
			}
			break;

		case SHA384:
		case SHA512:
			{
				unsigned char *puc;
				//Compute number of bytes mod 128
				unsigned int uiCount = (m_aoui64Bits[0].m_uiRight >> 3) & (BLOCKSIZE2-1);
				//Set the first char of padding to 0x80. This is safe since there is
				//always at least one byte free
				puc = m_aucIn + uiCount;
				*puc++ = 0x80;
				//Bytes of padding needed to make 128 bytes
				uiCount = BLOCKSIZE2 - uiCount - 1;
				//Pad out to 112 mod 128
				if(uiCount < 16)
				{
					//Two lots of padding: Pad the first block to 128 bytes
					memset(puc, 0, uiCount);
					Transform();
					//Now fill the next block with 112 bytes
					memset(m_aucIn, 0, BLOCKSIZE2-16);
				}
				else
				{
					//Pad block to 112 bytes
					memset(puc, 0, uiCount - 16);
				}
				//Append length in bits and transform
				Word2Bytes(m_aoui64Bits[1], &m_aucIn[BLOCKSIZE2-16]);
				Word2Bytes(m_aoui64Bits[0], &m_aucIn[BLOCKSIZE2-8]);
				Transform();
				switch(m_iMethod)
				{
					case SHA384:
						{
							for(int i=0; i<SHA384LENGTH; i++,pcDigest+=8)
								Word2Bytes(m_aoui64Buf[i], reinterpret_cast<unsigned char*>(pcDigest));
						}
						break;

					case SHA512:
						{
							for(int i=0; i<SHA512LENGTH; i++,pcDigest+=8)
								Word2Bytes(m_aoui64Buf[i], reinterpret_cast<unsigned char*>(pcDigest));
						}
						break;
				}
			}
			break;
	}
	//Reinitialize
	Reset();
}

//Reset current operation in order to prepare a new one
void CSHA::Reset()

⌨️ 快捷键说明

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