git-svn-id: svn://10.65.10.50/branches/R_10_00@22976 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			537 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			537 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*****************************************************************************************
 | 
						|
 | 
						|
***		MD5Checksum.cpp: implementation of the MD5Checksum class.
 | 
						|
 | 
						|
***		Developed by Langfine Ltd. 
 | 
						|
***		Released to the public domain 12/Nov/2001.
 | 
						|
***		Please visit our website www.langfine.com
 | 
						|
 | 
						|
***		Any modifications must be clearly commented to distinguish them from Langfine's 
 | 
						|
***		original source code. Please advise Langfine of useful modifications so that we 
 | 
						|
***		can make them generally available. 
 | 
						|
 | 
						|
*****************************************************************************************/
 | 
						|
 | 
						|
 | 
						|
/****************************************************************************************
 | 
						|
This software is derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. 
 | 
						|
Incorporation of this statement is a condition of use; please see the RSA
 | 
						|
Data Security Inc copyright notice below:-
 | 
						|
 | 
						|
Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
 | 
						|
rights reserved.
 | 
						|
 | 
						|
RSA Data Security, Inc. makes no representations concerning either
 | 
						|
the merchantability of this software or the suitability of this
 | 
						|
software for any particular purpose. It is provided "as is"
 | 
						|
without express or implied warranty of any kind.
 | 
						|
 | 
						|
These notices must be retained in any copies of any part of this
 | 
						|
documentation and/or software.
 | 
						|
 | 
						|
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
 | 
						|
rights reserved.
 | 
						|
License to copy and use this software is granted provided that it
 | 
						|
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
 | 
						|
Algorithm" in all material mentioning or referencing this software
 | 
						|
or this function.
 | 
						|
License is also granted to make and use derivative works provided
 | 
						|
that such works are identified as "derived from the RSA Data
 | 
						|
Security, Inc. MD5 Message-Digest Algorithm" in all material
 | 
						|
mentioning or referencing the derived work.
 | 
						|
RSA Data Security, Inc. makes no representations concerning either
 | 
						|
the merchantability of this software or the suitability of this
 | 
						|
software for any particular purpose. It is provided "as is"
 | 
						|
without express or implied warranty of any kind.
 | 
						|
 | 
						|
These notices must be retained in any copies of any part of this
 | 
						|
documentation and/or software.
 | 
						|
*****************************************************************************************/
 | 
						|
 | 
						|
/****************************************************************************************
 | 
						|
This implementation of the RSA MD5 Algorithm was written by Langfine Ltd 
 | 
						|
(www.langfine.com).
 | 
						|
 | 
						|
Langfine Ltd makes no representations concerning either
 | 
						|
the merchantability of this software or the suitability of this
 | 
						|
software for any particular purpose. It is provided "as is"
 | 
						|
without express or implied warranty of any kind.
 | 
						|
 | 
						|
In addition to the above, Langfine make no warrant or assurances regarding the 
 | 
						|
accuracy of this implementation of the MD5 checksum algorithm nor any assurances regarding
 | 
						|
its suitability for any purposes.
 | 
						|
 | 
						|
This implementation may be used freely provided that Langfine is credited
 | 
						|
in a copyright or similar notices (eg, RSA MD5 Algorithm implemented by Langfine
 | 
						|
Ltd.) and provided that the RSA Data Security notices are complied with.
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
#include "wxinc.h"
 | 
						|
 | 
						|
#include "MD5Checksum.h"
 | 
						|
#include "MD5ChecksumDefines.h"
 | 
						|
 | 
						|
#include <wx/file.h>
 | 
						|
#include "wx/filename.h"
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::GetMD5
 | 
						|
DETAILS:		static, public
 | 
						|
DESCRIPTION:	Gets the MD5 checksum for a specified file
 | 
						|
RETURNS:		wxString : the hexadecimal MD5 checksum for the specified file
 | 
						|
ARGUMENTS:		wxString& strFilePath : the full pathname of the specified file
 | 
						|
NOTES:			Provides an interface to the wxMD5Checksum class. 'strFilePath' name should 
 | 
						|
				hold the full pathname of the file, eg C:\My Documents\Arcticle.txt.
 | 
						|
				NB. If any problems occur with opening or reading this file, a CFileException
 | 
						|
				will be thrown; callers of this function should be ready to catch this 
 | 
						|
				exception.
 | 
						|
*****************************************************************************************/
 | 
						|
wxString wxMD5Checksum::GetMD5(const wxString& strFilePath)
 | 
						|
{
 | 
						|
  if(!wxFileName::FileExists(strFilePath))
 | 
						|
    return wxEmptyString;
 | 
						|
 | 
						|
  //open the file as a binary file in readonly mode, denying write access 
 | 
						|
  wxFile File(strFilePath, wxFile::read);
 | 
						|
	//the file has been successfully opened, so now get and return its checksum
 | 
						|
	return GetMD5(File);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::GetMD5
 | 
						|
DETAILS:		static, public
 | 
						|
DESCRIPTION:	Gets the MD5 checksum for a specified file
 | 
						|
RETURNS:		wxString : the hexadecimal MD5 checksum for the specified file
 | 
						|
ARGUMENTS:		wxFile& File : the specified file
 | 
						|
NOTES:			Provides an interface to the wxMD5Checksum class. 'File' should be open in 
 | 
						|
				binary readonly mode before calling this function. 
 | 
						|
				NB. Callers of this function should be ready to catch any CFileException
 | 
						|
				thrown by the wxFile functions
 | 
						|
*****************************************************************************************/
 | 
						|
wxString wxMD5Checksum::GetMD5(wxFile& File)
 | 
						|
{
 | 
						|
		wxMD5Checksum MD5Checksum;		//checksum object	
 | 
						|
		int nLength = 0;				//number of bytes read from the file
 | 
						|
		const int nBufferSize = 1024;	//checksum the file in blocks of 1024 bytes
 | 
						|
		unsigned char Buffer[nBufferSize];		//buffer for data read from the file
 | 
						|
 | 
						|
		//checksum the file in blocks of 1024 bytes
 | 
						|
		while ((nLength = File.Read( Buffer, nBufferSize )) > 0 )
 | 
						|
		{
 | 
						|
			MD5Checksum.Update( Buffer, nLength );
 | 
						|
		}
 | 
						|
 | 
						|
		//finalise the checksum and return it
 | 
						|
		return MD5Checksum.Final();
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::GetMD5
 | 
						|
DETAILS:		static, public
 | 
						|
DESCRIPTION:	Gets the MD5 checksum for data in a unsigned char array
 | 
						|
RETURNS:		wxString : the hexadecimal MD5 checksum for the specified data
 | 
						|
ARGUMENTS:		unsigned char* pBuf  :	pointer to the unsigned char array
 | 
						|
				unsigned int nLength :	number of BYTEs of data to be checksumed
 | 
						|
NOTES:			Provides an interface to the wxMD5Checksum class. Any data that can
 | 
						|
				be cast to a unsigned char array of known length can be checksummed by this
 | 
						|
				function. Typically, wxString and char arrays will be checksumed, 
 | 
						|
				although this function can be used to check the integrity of any unsigned char array. 
 | 
						|
				A buffer of zero length can be checksummed; all buffers of zero length 
 | 
						|
				will return the same checksum. 
 | 
						|
*****************************************************************************************/
 | 
						|
wxString wxMD5Checksum::GetMD5(unsigned char* pBuf, unsigned int nLength)
 | 
						|
{
 | 
						|
	//calculate and return the checksum
 | 
						|
	wxMD5Checksum MD5Checksum;
 | 
						|
	MD5Checksum.Update( pBuf, nLength );
 | 
						|
	return MD5Checksum.Final();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::RotateLeft
 | 
						|
DETAILS:		private
 | 
						|
DESCRIPTION:	Rotates the bits in a 32 bit unsigned long left by a specified amount
 | 
						|
RETURNS:		The rotated unsigned long 
 | 
						|
ARGUMENTS:		unsigned long x : the value to be rotated
 | 
						|
				int n   : the number of bits to rotate by
 | 
						|
*****************************************************************************************/
 | 
						|
unsigned long wxMD5Checksum::RotateLeft(unsigned long x, int n)
 | 
						|
{
 | 
						|
	//check that unsigned long is 4 bytes long - true in Visual C++ 6 and 32 bit Windows
 | 
						|
	wxASSERT( sizeof(x) == 4 );
 | 
						|
 | 
						|
	//rotate and return x
 | 
						|
	return (x << n) | (x >> (32-n));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::FF
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	Implementation of basic MD5 transformation algorithm
 | 
						|
RETURNS:		none
 | 
						|
ARGUMENTS:		unsigned long &A, B, C, D : Current (partial) checksum
 | 
						|
				unsigned long X           : Input data
 | 
						|
				unsigned long S			  : MD5_SXX Transformation constant
 | 
						|
				unsigned long T			  :	MD5_TXX Transformation constant
 | 
						|
NOTES:			None
 | 
						|
*****************************************************************************************/
 | 
						|
void wxMD5Checksum::FF( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T)
 | 
						|
{
 | 
						|
	unsigned long F = (B & C) | (~B & D);
 | 
						|
	A += F + X + T;
 | 
						|
	A = RotateLeft(A, S);
 | 
						|
	A += B;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::GG
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	Implementation of basic MD5 transformation algorithm
 | 
						|
RETURNS:		none
 | 
						|
ARGUMENTS:		unsigned long &A, B, C, D : Current (partial) checksum
 | 
						|
				unsigned long X           : Input data
 | 
						|
				unsigned long S			  : MD5_SXX Transformation constant
 | 
						|
				unsigned long T			  :	MD5_TXX Transformation constant
 | 
						|
NOTES:			None
 | 
						|
*****************************************************************************************/
 | 
						|
void wxMD5Checksum::GG( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T)
 | 
						|
{
 | 
						|
	unsigned long G = (B & D) | (C & ~D);
 | 
						|
	A += G + X + T;
 | 
						|
	A = RotateLeft(A, S);
 | 
						|
	A += B;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::HH
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	Implementation of basic MD5 transformation algorithm
 | 
						|
RETURNS:		none
 | 
						|
ARGUMENTS:		unsigned long &A, B, C, D : Current (partial) checksum
 | 
						|
				unsigned long X           : Input data
 | 
						|
				unsigned long S			  : MD5_SXX Transformation constant
 | 
						|
				unsigned long T			  :	MD5_TXX Transformation constant
 | 
						|
NOTES:			None
 | 
						|
*****************************************************************************************/
 | 
						|
void wxMD5Checksum::HH( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T)
 | 
						|
{
 | 
						|
	unsigned long H = (B ^ C ^ D);
 | 
						|
	A += H + X + T;
 | 
						|
	A = RotateLeft(A, S);
 | 
						|
	A += B;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::II
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	Implementation of basic MD5 transformation algorithm
 | 
						|
RETURNS:		none
 | 
						|
ARGUMENTS:		unsigned long &A, B, C, D : Current (partial) checksum
 | 
						|
				unsigned long X           : Input data
 | 
						|
				unsigned long S			  : MD5_SXX Transformation constant
 | 
						|
				unsigned long T			  :	MD5_TXX Transformation constant
 | 
						|
NOTES:			None
 | 
						|
*****************************************************************************************/
 | 
						|
void wxMD5Checksum::II( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T)
 | 
						|
{
 | 
						|
	unsigned long I = (C ^ (B | ~D));
 | 
						|
	A += I + X + T;
 | 
						|
	A = RotateLeft(A, S);
 | 
						|
	A += B;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::ByteToDWord
 | 
						|
DETAILS:		private
 | 
						|
DESCRIPTION:	Transfers the data in an 8 bit array to a 32 bit array
 | 
						|
RETURNS:		void
 | 
						|
ARGUMENTS:		unsigned long* Output : the 32 bit (unsigned long) destination array 
 | 
						|
				unsigned char* Input	  : the 8 bit (unsigned char) source array
 | 
						|
				unsigned int nLength  : the number of 8 bit data items in the source array
 | 
						|
NOTES:			Four BYTES from the input array are transferred to each unsigned long entry
 | 
						|
				of the output array. The first unsigned char is transferred to the bits (0-7) 
 | 
						|
				of the output unsigned long, the second unsigned char 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 wxMD5Checksum::ByteToDWord(unsigned long* Output, unsigned char* Input, unsigned int nLength)
 | 
						|
{
 | 
						|
	//entry invariants
 | 
						|
	wxASSERT( nLength % 4 == 0 );
 | 
						|
 | 
						|
	//initialisations
 | 
						|
	unsigned int i=0;	//index to Output array
 | 
						|
	unsigned int j=0;	//index to Input array
 | 
						|
 | 
						|
	//transfer the data by shifting and copying
 | 
						|
	for ( ; j < nLength; i++, j += 4)
 | 
						|
	{
 | 
						|
		Output[i] = (unsigned long)Input[j]			| 
 | 
						|
					(unsigned long)Input[j+1] << 8	| 
 | 
						|
					(unsigned long)Input[j+2] << 16 | 
 | 
						|
					(unsigned long)Input[j+3] << 24;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::Transform
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	MD5 basic transformation algorithm;  transforms 'm_lMD5'
 | 
						|
RETURNS:		void
 | 
						|
ARGUMENTS:		unsigned char 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 wxMD5Checksum::Transform(unsigned char Block[64])
 | 
						|
{
 | 
						|
	//initialise local data with current checksum
 | 
						|
	unsigned long a = m_lMD5[0];
 | 
						|
	unsigned long b = m_lMD5[1];
 | 
						|
	unsigned long c = m_lMD5[2];
 | 
						|
	unsigned long d = m_lMD5[3];
 | 
						|
 | 
						|
	//copy BYTES from input 'Block' to an array of ULONGS 'X'
 | 
						|
	unsigned long 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:	wxMD5Checksum
 | 
						|
DESCRIPTION:	Initialises member data
 | 
						|
ARGUMENTS:		None
 | 
						|
NOTES:			None
 | 
						|
*****************************************************************************************/
 | 
						|
wxMD5Checksum::wxMD5Checksum()
 | 
						|
{
 | 
						|
	// 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:		wxMD5Checksum::DWordToByte
 | 
						|
DETAILS:		private
 | 
						|
DESCRIPTION:	Transfers the data in an 32 bit array to a 8 bit array
 | 
						|
RETURNS:		void
 | 
						|
ARGUMENTS:		unsigned char* Output  : the 8 bit destination array 
 | 
						|
				unsigned long* Input  : the 32 bit source array
 | 
						|
				unsigned int nLength  : the number of 8 bit data items in the source array
 | 
						|
NOTES:			One unsigned long from the input array is transferred into four BYTES 
 | 
						|
				in the output array. The first (0-7) bits of the first unsigned long are 
 | 
						|
				transferred to the first output unsigned char, bits bits 8-15 are transferred from
 | 
						|
				the second unsigned char 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 wxMD5Checksum::DWordToByte(unsigned char* Output, unsigned long* Input, unsigned int nLength )
 | 
						|
{
 | 
						|
	//entry invariants
 | 
						|
	wxASSERT( nLength % 4 == 0 );
 | 
						|
 | 
						|
	//transfer the data by shifting and copying
 | 
						|
	unsigned int i = 0;
 | 
						|
	unsigned int j = 0;
 | 
						|
	for ( ; j < nLength; i++, j += 4) 
 | 
						|
	{
 | 
						|
		Output[j] =   (UCHAR)(Input[i] & 0xff);
 | 
						|
		Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff);
 | 
						|
		Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff);
 | 
						|
		Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::Final
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	Implementation of main MD5 checksum algorithm; ends the checksum calculation.
 | 
						|
RETURNS:		wxString : 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.) 
 | 
						|
*****************************************************************************************/
 | 
						|
wxString wxMD5Checksum::Final()
 | 
						|
{
 | 
						|
	//Save number of bits
 | 
						|
	unsigned char Bits[8];
 | 
						|
	DWordToByte( Bits, m_nCount, 8 );
 | 
						|
 | 
						|
	//Pad out to 56 mod 64.
 | 
						|
	unsigned int nIndex = (unsigned int)((m_nCount[0] >> 3) & 0x3f);
 | 
						|
	unsigned int 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 wxString
 | 
						|
	wxString strMD5;
 | 
						|
	for ( int i=0; i < nMD5Size; i++) 
 | 
						|
	{
 | 
						|
		wxString Str;
 | 
						|
		if (lpszMD5[i] == 0) {
 | 
						|
			Str = wxT("00");
 | 
						|
		}
 | 
						|
		else if (lpszMD5[i] <= 15) 	{
 | 
						|
			Str.Printf(wxT("0%x"),lpszMD5[i]);
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			Str.Printf(wxT("%x"),lpszMD5[i]);
 | 
						|
		}
 | 
						|
 | 
						|
		wxASSERT( Str.Length() == 2 );
 | 
						|
		strMD5 += Str;
 | 
						|
	}
 | 
						|
	wxASSERT( strMD5.Length() == 32 );
 | 
						|
	return strMD5;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************************************
 | 
						|
FUNCTION:		wxMD5Checksum::Update
 | 
						|
DETAILS:		protected
 | 
						|
DESCRIPTION:	Implementation of main MD5 checksum algorithm
 | 
						|
RETURNS:		void
 | 
						|
ARGUMENTS:		unsigned char* Input    : input block
 | 
						|
				unsigned int nInputLen : length of input block
 | 
						|
NOTES:			Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input'
 | 
						|
*****************************************************************************************/
 | 
						|
void wxMD5Checksum::Update( unsigned char* Input,	unsigned long nInputLen )
 | 
						|
{
 | 
						|
	//Compute number of bytes mod 64
 | 
						|
	unsigned int nIndex = (unsigned int)((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.
 | 
						|
	unsigned int i=0;		
 | 
						|
	unsigned int 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;
 | 
						|
	}
 | 
						|
 | 
						|
	// Buffer remaining input
 | 
						|
	memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i);
 | 
						|
}
 | 
						|
 | 
						|
 |