| 
 | 
 
 
 楼主 |
发表于 2006-7-18 13:33:47
|
显示全部楼层
 
 
 
 /*****************************************************************************************  FUNCTION: CMD5Checksum::II  DETAILS: protected  DESCRIPTION: Implementation of basic MD5 transformation algorithm  RETURNS: none  ARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum  DWORD X : Input data  DWORD S : MD5_SXX Transformation constant  DWORD T : MD5_TXX Transformation constant  NOTES: None  *****************************************************************************************/  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;  } 
  /*****************************************************************************************  FUNCTION: CMD5Checksum::ByteToDWord  DETAILS: private  DESCRIPTION: Transfers the data in an 8 bit array to a 32 bit array  RETURNS: void  ARGUMENTS: DWORD* Output : the 32 bit (unsigned long) destination array  BYTE* Input : the 8 bit (unsigned char) source array  UINT nLength : the number of 8 bit data items in the source array  NOTES: Four BYTES from the input array are transferred to each DWORD entry  of the output array. The first BYTE is transferred to the bits (0-7)  of the output DWORD, the second BYTE to bits 8-15 etc.  The algorithm assumes that the input array is a multiple of 4 bytes long  so that there is a perfect fit into the array of 32 bit words.  *****************************************************************************************/  void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength)  {  //entry invariants  ASSERT( nLength % 4 == 0 );  ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) );  ASSERT( AfxIsValidAddress(Input, nLength, FALSE) ); 
  //initialisations  UINT i=0; //index to Output array  UINT j=0; //index to Input array 
  //transfer the data by shifting and copying  for ( ; j < nLength; i++, j += 4)  {  Output = (ULONG)Input[j] |  (ULONG)Input[j+1] << 8 |  (ULONG)Input[j+2] << 16 |  (ULONG)Input[j+3] << 24;  }  } 
  /*****************************************************************************************  FUNCTION: CMD5Checksum::Transform  DETAILS: protected  DESCRIPTION: MD5 basic transformation algorithm; transforms 'm_lMD5'  RETURNS: void  ARGUMENTS: BYTE Block[64]  NOTES: An MD5 checksum is calculated by four rounds of 'Transformation'.  The MD5 checksum currently held in m_lMD5 is merged by the  transformation process with data passed in 'Block'.  *****************************************************************************************/  void CMD5Checksum::Transform(BYTE Block[64])  {  //initialise local data with current checksum  ULONG a = m_lMD5[0];  ULONG b = m_lMD5[1];  ULONG c = m_lMD5[2];  ULONG d = m_lMD5[3]; 
  //copy BYTES from input 'Block' to an array of ULONGS 'X'  ULONG X[16];  ByteToDWord( X, Block, 64 ); 
  //Perform Round 1 of the transformation  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); 
  //Perform Round 2 of the transformation  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); 
  //Perform Round 3 of the transformation  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); 
  //Perform Round 4 of the transformation  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); 
  //add the transformed values to the current checksum  m_lMD5[0] += a;  m_lMD5[1] += b;  m_lMD5[2] += c;  m_lMD5[3] += d;  } 
  /*****************************************************************************************  CONSTRUCTOR: CMD5Checksum  DESCRIPTION: Initialises member data  ARGUMENTS: None  NOTES: None  *****************************************************************************************/  CMD5Checksum::CMD5Checksum()  {  // zero members  memset( m_lpszBuffer, 0, 64 );  m_nCount[0] = m_nCount[1] = 0; 
  // Load magic state initialization constants  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;  } 
  /*****************************************************************************************  FUNCTION: CMD5Checksum: WordToByte  DETAILS: private  DESCRIPTION: Transfers the data in an 32 bit array to a 8 bit array  RETURNS: void  ARGUMENTS: BYTE* Output : the 8 bit destination array  DWORD* Input : the 32 bit source array  UINT nLength : the number of 8 bit data items in the source array  NOTES: One DWORD from the input array is transferred into four BYTES  in the output array. The first (0-7) bits of the first DWORD are  transferred to the first output BYTE, bits bits 8-15 are transferred from  the second BYTE etc. 
  The algorithm assumes that the output array is a multiple of 4 bytes long  so that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs.  *****************************************************************************************/  void CMD5Checksum: WordToByte(BYTE* Output, DWORD* Input, UINT nLength )  {  //entry invariants  ASSERT( nLength % 4 == 0 );  ASSERT( AfxIsValidAddress(Output, nLength, TRUE) );  ASSERT( AfxIsValidAddress(Input, nLength/4, FALSE) ); 
  //transfer the data by shifting and copying  UINT i = 0;  UINT j = 0;  for ( ; j < nLength; i++, j += 4)  {  Output[j] = (UCHAR)(Input & 0xff);  Output[j+1] = (UCHAR)((Input >> 8) & 0xff);  Output[j+2] = (UCHAR)((Input >> 16) & 0xff);  Output[j+3] = (UCHAR)((Input >> 24) & 0xff);  }  } 
  /*****************************************************************************************  FUNCTION: CMD5Checksum::Final  DETAILS: protected  DESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checksum calculation.  RETURNS: CString : the final hexadecimal MD5 checksum result  ARGUMENTS: None  NOTES: Performs the final MD5 checksum calculation ('Update' does most of the work,  this function just finishes the calculation.)  *****************************************************************************************/  CString CMD5Checksum::Final()  {  //Save number of bits  BYTE Bits[8];  DWordToByte( Bits, m_nCount, 8 ); 
  //Pad out to 56 mod 64.  UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3f);  UINT nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);  Update( PADDING, nPadLen ); 
  //Append length (before padding)  Update( Bits, 8 ); 
  //Store final state in 'lpszMD5'  const int nMD5Size = 16;  unsigned char lpszMD5[ nMD5Size ];  DWordToByte( lpszMD5, m_lMD5, nMD5Size ); 
  //Convert the hexadecimal checksum to a CString  CString strMD5;  for ( int i=0; i < nMD5Size; i++)  {  CString Str;  if (lpszMD5 == 0) {  Str = CString("00");  }  else if (lpszMD5 <= 15) {  Str.Format("0%x",lpszMD5);  }  else {  Str.Format("%x",lpszMD5);  } 
  ASSERT( Str.GetLength() == 2 );  strMD5 += Str;  }  ASSERT( strMD5.GetLength() == 32 );  return strMD5;  } 
  /*****************************************************************************************  FUNCTION: CMD5Checksum::Update  DETAILS: protected  DESCRIPTION: Implementation of main MD5 checksum algorithm  RETURNS: void  ARGUMENTS: BYTE* Input : input block  UINT nInputLen : length of input block  NOTES: Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input'  *****************************************************************************************/  void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen )  {  //Compute number of bytes mod 64  UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F); 
  //Update number of bits  if ( ( m_nCount[0] += nInputLen << 3 ) < ( nInputLen << 3) )  {  m_nCount[1]++;  }  m_nCount[1] += (nInputLen >> 29); 
  //Transform as many times as possible.  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 );  }  nIndex = 0;  }  else  {  i = 0;  } 
  // Buffer remaining input  memcpy( &m_lpszBuffer[nIndex], &Input, nInputLen-i);  } 
  |   
 
 
 
 |