00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "StdAfx.h"
00027
00028 #include "MD5.h"
00029
00031
00032
00033 CMD5::CMD5()
00034 {
00035 Reset();
00036 }
00037
00038 CMD5::~CMD5()
00039 {
00040 }
00041
00042 static unsigned char MD5_PADDING[64] = {
00043 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00044 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00045 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00046 };
00047
00048 extern "C" void MD5_Add_p5(CMD5*, LPCVOID pData, DWORD nLength);
00049
00051
00052
00053 void CMD5::Reset()
00054 {
00055 m_nCount[0] = m_nCount[1] = 0;
00056
00057 m_nState[0] = 0x67452301;
00058 m_nState[1] = 0xefcdab89;
00059 m_nState[2] = 0x98badcfe;
00060 m_nState[3] = 0x10325476;
00061 }
00062
00064
00065
00066 void CMD5::Add(LPCVOID pData, DWORD nLength)
00067 {
00068 MD5_Add_p5(this, pData, nLength);
00069 }
00070
00072
00073
00074 void CMD5::Finish()
00075 {
00076 unsigned int bits[2], index = 0;
00077
00078 bits[1] = ( m_nCount[1] << 3 ) + ( m_nCount[0] >> 29);
00079 bits[0] = m_nCount[0] << 3;
00080
00081 index = (unsigned int)(m_nCount[0] & 0x3f);
00082 MD5_Add_p5(this, MD5_PADDING, (index < 56) ? (56 - index) : (120 - index) );
00083
00084 MD5_Add_p5(this, bits, 8 );
00085 }
00086
00088
00089
00090 void CMD5::GetHash(MD5* pHash)
00091 {
00092
00093 memcpy(pHash, m_nState, 16);
00094 }
00095
00097
00098
00099 CString CMD5::HashToString(const MD5* pHash, BOOL bURN)
00100 {
00101 CString str;
00102
00103 str.Format( bURN ?
00104 _T("md5:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x") :
00105 _T("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
00106 pHash->n[0], pHash->n[1], pHash->n[2], pHash->n[3],
00107 pHash->n[4], pHash->n[5], pHash->n[6], pHash->n[7],
00108 pHash->n[8], pHash->n[9], pHash->n[10], pHash->n[11],
00109 pHash->n[12], pHash->n[13], pHash->n[14], pHash->n[15] );
00110
00111 return str;
00112 }
00113
00115
00116
00117 BOOL CMD5::HashFromString(LPCTSTR pszHash, MD5* pMD5)
00118 {
00119 if ( _tcslen( pszHash ) < 32 ) return FALSE;
00120
00121 BYTE* pOut = (BYTE*)pMD5;
00122
00123 for ( int nPos = 16 ; nPos ; nPos--, pOut++ )
00124 {
00125 if ( *pszHash >= '0' && *pszHash <= '9' )
00126 *pOut = ( *pszHash - '0' ) << 4;
00127 else if ( *pszHash >= 'A' && *pszHash <= 'F' )
00128 *pOut = ( *pszHash - 'A' + 10 ) << 4;
00129 else if ( *pszHash >= 'a' && *pszHash <= 'f' )
00130 *pOut = ( *pszHash - 'a' + 10 ) << 4;
00131 pszHash++;
00132 if ( *pszHash >= '0' && *pszHash <= '9' )
00133 *pOut |= ( *pszHash - '0' );
00134 else if ( *pszHash >= 'A' && *pszHash <= 'F' )
00135 *pOut |= ( *pszHash - 'A' + 10 );
00136 else if ( *pszHash >= 'a' && *pszHash <= 'f' )
00137 *pOut |= ( *pszHash - 'a' + 10 );
00138 pszHash++;
00139 }
00140
00141 return TRUE;
00142 }
00143
00144 BOOL CMD5::HashFromURN(LPCTSTR pszHash, MD5* pMD5)
00145 {
00146 if ( pszHash == NULL ) return FALSE;
00147
00148 int nLen = _tcslen( pszHash );
00149
00150 if ( nLen >= 8 + 32 && _tcsnicmp( pszHash, _T("urn:md5:"), 8 ) == 0 )
00151 {
00152 return HashFromString( pszHash + 8, pMD5 );
00153 }
00154 else if ( nLen >= 4 + 32 && _tcsnicmp( pszHash, _T("md5:"), 4 ) == 0 )
00155 {
00156 return HashFromString( pszHash + 4, pMD5 );
00157 }
00158
00159 return FALSE;
00160 }