VC++ MD5检验

头文件申明(CMD5Checksum.h):

#ifndef MD5_CHECK_SUM_HEAD
#define MD5_CHECK_SUM_HEAD
#pragma once

//初始常量
#define MD5_INIT_STATE_0	0x67452301
#define MD5_INIT_STATE_1	0xefcdab89
#define MD5_INIT_STATE_2	0x98badcfe
#define MD5_INIT_STATE_3	0x10325476

//转换常量
#define MD5_S11		7
#define MD5_S12		12
#define MD5_S13		17
#define MD5_S14		22
#define MD5_S21		5
#define MD5_S22		9
#define MD5_S23		14
#define MD5_S24		20
#define MD5_S31		4
#define MD5_S32		11
#define MD5_S33		16
#define MD5_S34		23
#define MD5_S41		6
#define MD5_S42		10
#define MD5_S43		15
#define MD5_S44		21

//1轮转换常量
#define MD5_T01		0xd76aa478 
#define MD5_T02		0xe8c7b756 
#define MD5_T03		0x242070db 
#define MD5_T04		0xc1bdceee 
#define MD5_T05		0xf57c0faf 
#define MD5_T06		0x4787c62a 
#define MD5_T07		0xa8304613 
#define MD5_T08		0xfd469501 
#define MD5_T09		0x698098d8 
#define MD5_T10		0x8b44f7af 
#define MD5_T11		0xffff5bb1 
#define MD5_T12		0x895cd7be 
#define MD5_T13		0x6b901122 
#define MD5_T14		0xfd987193 
#define MD5_T15		0xa679438e 
#define MD5_T16		0x49b40821 

//2轮转换常量
#define MD5_T17		0xf61e2562 
#define MD5_T18		0xc040b340 
#define MD5_T19		0x265e5a51 
#define MD5_T20		0xe9b6c7aa 
#define MD5_T21		0xd62f105d 
#define MD5_T22		0x02441453 
#define MD5_T23		0xd8a1e681 
#define MD5_T24		0xe7d3fbc8 
#define MD5_T25		0x21e1cde6 
#define MD5_T26		0xc33707d6 
#define MD5_T27		0xf4d50d87 
#define MD5_T28		0x455a14ed 
#define MD5_T29		0xa9e3e905 
#define MD5_T30		0xfcefa3f8 
#define MD5_T31		0x676f02d9 
#define MD5_T32		0x8d2a4c8a 

//3轮转换常量
#define MD5_T33		0xfffa3942 
#define MD5_T34		0x8771f681 
#define MD5_T35		0x6d9d6122 
#define MD5_T36		0xfde5380c 
#define MD5_T37		0xa4beea44 
#define MD5_T38		0x4bdecfa9 
#define MD5_T39		0xf6bb4b60 
#define MD5_T40		0xbebfbc70 
#define MD5_T41		0x289b7ec6 
#define MD5_T42		0xeaa127fa 
#define MD5_T43		0xd4ef3085 
#define MD5_T44		0x04881d05 
#define MD5_T45		0xd9d4d039 
#define MD5_T46		0xe6db99e5 
#define MD5_T47		0x1fa27cf8 
#define MD5_T48		0xc4ac5665 

//4轮转换常量
#define MD5_T49		0xf4292244 
#define MD5_T50		0x432aff97 
#define MD5_T51		0xab9423a7 
#define MD5_T52		0xfc93a039 
#define MD5_T53		0x655b59c3 
#define MD5_T54		0x8f0ccc92 
#define MD5_T55		0xffeff47d 
#define MD5_T56		0x85845dd1 
#define MD5_T57		0x6fa87e4f 
#define MD5_T58		0xfe2ce6e0 
#define MD5_T59		0xa3014314 
#define MD5_T60		0x4e0811a1 
#define MD5_T61		0xf7537e82 
#define MD5_T62		0xbd3af235 
#define MD5_T63		0x2ad7d2bb 
#define MD5_T64		0xeb86d391 


//填充数据
static unsigned char PADDING[64] = {
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

//MD5校验
class CMD5Checksum
{
	//存储变量
private:
	BYTE                  m_lpszBuffer[64];             //输入缓冲
	ULONG                 m_nCount[2];                  //位数计数
	ULONG                 m_lMD5[4];                    //MD5校验和

	//函数定义
protected:
	CMD5Checksum();
	virtual ~CMD5Checksum();

	//静态函数
public:
	static CString GetMD5(BYTE* pBuf, UINT nLength);
	static CString GetMD5(CFile& File);
	static CString GetMD5(const CString& strFilePath);

    //辅助函数
protected:
	CString Final();

	//辅助函数
protected:
	VOID Transform(BYTE Block[64]);
	VOID Update(BYTE* Input, ULONG nInputLen);
	VOID DWordToByte(BYTE* Output, DWORD* Input, UINT nLength);
	VOID ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength);

	//内联函数
protected:
	inline DWORD RotateLeft(DWORD x, int n);
	inline VOID FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
	inline VOID GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
	inline VOID HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
	inline VOID II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);
};

#endif

源码实现(CMD5Checksum.cpp):

#include "Stdafx.h"
#include "CMD5CheckSum.h"

//构造函数
CMD5Checksum::CMD5Checksum()
{
	//初始成员
	memset( m_lpszBuffer, 0, 64 );
	m_nCount[0] = m_nCount[1] = 0;

	//初始变量
	m_lMD5[0] = MD5_INIT_STATE_0;
	m_lMD5[1] = MD5_INIT_STATE_1;
	m_lMD5[2] = MD5_INIT_STATE_2;
	m_lMD5[3] = MD5_INIT_STATE_3;
}

//析构函数
CMD5Checksum::~CMD5Checksum()
{
}

//获取校验和
CString CMD5Checksum::GetMD5(const CString& strFilePath)
{
	//打开文件
	CFile File;
	if(File.Open(strFilePath, CFile::modeRead|CFile::shareDenyNone)==false)
	{
		return TEXT("");
	}

	//返回校验和
	return GetMD5(File);
}

//获取校验和
CString CMD5Checksum::GetMD5(CFile& File)
{
	try
	{
		//变量定义
		CWHMD5Checksum MD5Checksum;  
		int nLength = 0;  
		const int nBufferSize = 1024; 
		BYTE Buffer[nBufferSize];  

		//校验文件
		while ((nLength = File.Read( Buffer, nBufferSize )) > 0 )
		{
			MD5Checksum.Update( Buffer, nLength );
		}

		//完成校验
		return MD5Checksum.Final();
	}
	catch (CFileException* e )
	{
		TRACE0("CWHMD5Checksum::GetMD5: CFileException caught"); 
		throw e;
	}
}

//获取校验和
CString CMD5Checksum::GetMD5(BYTE* pBuf, UINT nLength)
{
	AfxIsValidAddress(pBuf,nLength,FALSE);

	//变量定义
	CWHMD5Checksum MD5Checksum;

	//计算校验和
	MD5Checksum.Update( pBuf, nLength );

	//完成校验
	return MD5Checksum.Final();
}

//
CString CMD5Checksum::Final()
{
	//变量定义
	BYTE Bits[8];
	DWordToByte( Bits, m_nCount, 8 );

	//变量定义
	UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3f);
	UINT nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);
	Update( PADDING, nPadLen );

	//更新数据
	Update( Bits, 8 );

	//变量定义
	const int nMD5Size = 16;
	unsigned char lpszMD5[ nMD5Size ];
	DWordToByte( lpszMD5, m_lMD5, nMD5Size );

	//转换类型
	CString strMD5;
	for ( int i=0; i < nMD5Size; i++) 
	{
		CString Str;
		if (lpszMD5[i] == 0) 
		{
			Str = CString("00");
		}
		else if (lpszMD5[i] <= 15)  
		{
			Str.Format(TEXT("0%x"),lpszMD5[i]);
		}
		else 
		{
			Str.Format(TEXT("%x"),lpszMD5[i]);
		}
		
		ASSERT( Str.GetLength() == 2 );
		strMD5 += Str;
	}

	//结果校验
	ASSERT( strMD5.GetLength() == 32 );
	return strMD5;
}

//转换数据
VOID CMD5Checksum::Transform(BYTE Block[64])
{
	//变量定义
	ULONG a = m_lMD5[0];
	ULONG b = m_lMD5[1];
	ULONG c = m_lMD5[2];
	ULONG d = m_lMD5[3];

	//变量定义
	ULONG X[16];

	//数据转换
	ByteToDWord( X, Block, 64 );

	//1轮转换
	FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01); 
	FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02); 
	FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03); 
	FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04); 
	FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05); 
	FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06); 
	FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07); 
	FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08); 
	FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09); 
	FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10); 
	FF (c, d, a, b, X[10], MD5_S13, MD5_T11); 
	FF (b, c, d, a, X[11], MD5_S14, MD5_T12); 
	FF (a, b, c, d, X[12], MD5_S11, MD5_T13); 
	FF (d, a, b, c, X[13], MD5_S12, MD5_T14); 
	FF (c, d, a, b, X[14], MD5_S13, MD5_T15); 
	FF (b, c, d, a, X[15], MD5_S14, MD5_T16); 

	//2轮转换
	GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17); 
	GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18); 
	GG (c, d, a, b, X[11], MD5_S23, MD5_T19); 
	GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20); 
	GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21); 
	GG (d, a, b, c, X[10], MD5_S22, MD5_T22); 
	GG (c, d, a, b, X[15], MD5_S23, MD5_T23); 
	GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24); 
	GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25); 
	GG (d, a, b, c, X[14], MD5_S22, MD5_T26); 
	GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27); 
	GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28); 
	GG (a, b, c, d, X[13], MD5_S21, MD5_T29); 
	GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30); 
	GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31); 
	GG (b, c, d, a, X[12], MD5_S24, MD5_T32); 

	//3轮转换
	HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); 
	HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34); 
	HH (c, d, a, b, X[11], MD5_S33, MD5_T35); 
	HH (b, c, d, a, X[14], MD5_S34, MD5_T36); 
	HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37); 
	HH (d, a, b, c, X[ 4], MD5_S32, MD5_T38); 
	HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39); 
	HH (b, c, d, a, X[10], MD5_S34, MD5_T40); 
	HH (a, b, c, d, X[13], MD5_S31, MD5_T41); 
	HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42); 
	HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43); 
	HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44); 
	HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45); 
	HH (d, a, b, c, X[12], MD5_S32, MD5_T46); 
	HH (c, d, a, b, X[15], MD5_S33, MD5_T47); 
	HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48); 

	//4轮转换
	II (a, b, c, d, X[ 0], MD5_S41, MD5_T49); 
	II (d, a, b, c, X[ 7], MD5_S42, MD5_T50); 
	II (c, d, a, b, X[14], MD5_S43, MD5_T51); 
	II (b, c, d, a, X[ 5], MD5_S44, MD5_T52); 
	II (a, b, c, d, X[12], MD5_S41, MD5_T53); 
	II (d, a, b, c, X[ 3], MD5_S42, MD5_T54); 
	II (c, d, a, b, X[10], MD5_S43, MD5_T55); 
	II (b, c, d, a, X[ 1], MD5_S44, MD5_T56); 
	II (a, b, c, d, X[ 8], MD5_S41, MD5_T57); 
	II (d, a, b, c, X[15], MD5_S42, MD5_T58); 
	II (c, d, a, b, X[ 6], MD5_S43, MD5_T59); 
	II (b, c, d, a, X[13], MD5_S44, MD5_T60); 
	II (a, b, c, d, X[ 4], MD5_S41, MD5_T61); 
	II (d, a, b, c, X[11], MD5_S42, MD5_T62); 
	II (c, d, a, b, X[ 2], MD5_S43, MD5_T63); 
	II (b, c, d, a, X[ 9], MD5_S44, MD5_T64); 

	//设置校验和
	m_lMD5[0] += a;
	m_lMD5[1] += b;
	m_lMD5[2] += c;
	m_lMD5[3] += d;
}

//更新数据
VOID CMD5Checksum::Update( BYTE* Input, ULONG nInputLen )
{
	//变量定义
	UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F);

	//更新位数
	if ( ( m_nCount[0] += nInputLen << 3 )  <  ( nInputLen << 3) )
	{
		m_nCount[1]++;
	}

	//设置变量
	m_nCount[1] += (nInputLen >> 29);

	//重复转换
	UINT i=0;  
	UINT nPartLen = 64 - nIndex;
	if (nInputLen >= nPartLen)  
	{
		memcpy( &m_lpszBuffer[nIndex], Input, nPartLen );
		Transform( m_lpszBuffer );
		for (i = nPartLen; i + 63 < nInputLen; i += 64) 
		{
			Transform( &Input[i] );
		}
		nIndex = 0;
	} 
	else 
	{
		i = 0;
	}

	//拷贝缓冲
	memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i);
}

//类型转换
VOID CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength)
{
	//参数校验
	ASSERT( nLength % 4 == 0 );
	ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) );
	ASSERT( AfxIsValidAddress(Input, nLength, FALSE) );

	//变量定义
	UINT nOutIndex=0; 
	UINT nLoopIndex=0; 

	//转换拷贝
	for ( ;nLoopIndex < nLength; nOutIndex++, nLoopIndex += 4)
	{
		Output[nOutIndex] = (ULONG)Input[nLoopIndex]	| 
							(ULONG)Input[nLoopIndex+1] << 8 | 
							(ULONG)Input[nLoopIndex+2] << 16 | 
							(ULONG)Input[nLoopIndex+3] << 24;
	}

	return;
}

//类型转换
VOID CMD5Checksum::DWordToByte(BYTE* Output, DWORD* Input, UINT nLength )
{
	//校验变量
	ASSERT( nLength % 4 == 0 );
	ASSERT( AfxIsValidAddress(Output, nLength, TRUE) );
	ASSERT( AfxIsValidAddress(Input, nLength/4, FALSE) );

	//转换拷贝
	UINT nInIndex = 0;
	UINT nLoopIndex = 0;
	for ( ; nLoopIndex < nLength; nInIndex++, nLoopIndex += 4) 
	{
		Output[nLoopIndex] =   (UCHAR)(Input[nInIndex] & 0xff);
		Output[nLoopIndex+1] = (UCHAR)((Input[nInIndex] >> 8) & 0xff);
		Output[nLoopIndex+2] = (UCHAR)((Input[nInIndex] >> 16) & 0xff);
		Output[nLoopIndex+3] = (UCHAR)((Input[nInIndex] >> 24) & 0xff);
	}

	return;
}

//
DWORD CMD5Checksum::RotateLeft(DWORD x, int n)
{
	//参数校验
	ASSERT( sizeof(x) == 4 );
	
	//返回结果
	return (x << n) | (x >> (32-n));
}


VOID CMD5Checksum::FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
{
	DWORD F = (B & C) | (~B & D);
	A += F + X + T;
	A = RotateLeft(A, S);
	A += B;
}

VOID CMD5Checksum::GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
{
	DWORD G = (B & D) | (C & ~D);
	A += G + X + T;
	A = RotateLeft(A, S);
	A += B;
}

VOID CMD5Checksum::HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
{
	DWORD H = (B ^ C ^ D);
	A += H + X + T;
	A = RotateLeft(A, S);
	A += B;
}

VOID CMD5Checksum::II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)
{
	DWORD I = (C ^ (B | ~D));
	A += I + X + T;
	A = RotateLeft(A, S);
	A += B;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值