D:/Zythum/DinoKod/Common/md5.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : md5.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 18/05/2003
00008 //      Modification    :
00009 //
00010 // RFC 1321 compliant MD5 implementation,
00011 // by Christophe Devine <devine@cr0.net>;
00012 // this program is licensed under the GPL.
00013 //---------------------------------------------------------------------------------------------
00014 #include "Common/Md5.h"
00015 
00016 //---------------------------------------------------------------------------------------------
00017 #define uint8  unsigned char
00018 #define uint32 unsigned long int
00019 
00020 struct md5_context
00021 {
00022     uint32 total[2];
00023     uint32 state[4];
00024     uint8 buffer[64];
00025 };
00026 
00027 void md5_starts( struct md5_context *ctx );
00028 void md5_update( struct md5_context *ctx, uint8 *input, uint32 length );
00029 void md5_finish( struct md5_context *ctx, uint8 digest[16] );
00030 //---------------------------------------------------------------------------------------------
00031 #define GET_UINT32(n,b,i)                                       \
00032 {                                                               \
00033     (n) = (uint32) ((uint8 *) b)[(i)]                           \
00034       | (((uint32) ((uint8 *) b)[(i)+1]) <<  8)                 \
00035       | (((uint32) ((uint8 *) b)[(i)+2]) << 16)                 \
00036       | (((uint32) ((uint8 *) b)[(i)+3]) << 24);                \
00037 }
00038 
00039 #define PUT_UINT32(n,b,i)                                       \
00040 {                                                               \
00041     (((uint8 *) b)[(i)]  ) = (uint8) (((n)      ) & 0xFF);      \
00042     (((uint8 *) b)[(i)+1]) = (uint8) (((n) >>  8) & 0xFF);      \
00043     (((uint8 *) b)[(i)+2]) = (uint8) (((n) >> 16) & 0xFF);      \
00044     (((uint8 *) b)[(i)+3]) = (uint8) (((n) >> 24) & 0xFF);      \
00045 }
00046 
00047 void md5_starts( struct md5_context *ctx )
00048 {
00049     ctx->total[0] = 0;
00050     ctx->total[1] = 0;
00051     ctx->state[0] = 0x67452301;
00052     ctx->state[1] = 0xEFCDAB89;
00053     ctx->state[2] = 0x98BADCFE;
00054     ctx->state[3] = 0x10325476;
00055 }
00056 
00057 void md5_process( struct md5_context *ctx, uint8 data[64] )
00058 {
00059     uint32 A, B, C, D, X[16];
00060 
00061     GET_UINT32( X[0],  data,  0 );
00062     GET_UINT32( X[1],  data,  4 );
00063     GET_UINT32( X[2],  data,  8 );
00064     GET_UINT32( X[3],  data, 12 );
00065     GET_UINT32( X[4],  data, 16 );
00066     GET_UINT32( X[5],  data, 20 );
00067     GET_UINT32( X[6],  data, 24 );
00068     GET_UINT32( X[7],  data, 28 );
00069     GET_UINT32( X[8],  data, 32 );
00070     GET_UINT32( X[9],  data, 36 );
00071     GET_UINT32( X[10], data, 40 );
00072     GET_UINT32( X[11], data, 44 );
00073     GET_UINT32( X[12], data, 48 );
00074     GET_UINT32( X[13], data, 52 );
00075     GET_UINT32( X[14], data, 56 );
00076     GET_UINT32( X[15], data, 60 );
00077 
00078 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00079 
00080 #define P(a,b,c,d,k,s,t)                                \
00081 {                                                       \
00082     a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
00083 }
00084 
00085     A = ctx->state[0];
00086     B = ctx->state[1];
00087     C = ctx->state[2];
00088     D = ctx->state[3];
00089 
00090 #define F(x,y,z) (z ^ (x & (y ^ z)))
00091 
00092     P( A, B, C, D,  0,  7, 0xD76AA478 );
00093     P( D, A, B, C,  1, 12, 0xE8C7B756 );
00094     P( C, D, A, B,  2, 17, 0x242070DB );
00095     P( B, C, D, A,  3, 22, 0xC1BDCEEE );
00096     P( A, B, C, D,  4,  7, 0xF57C0FAF );
00097     P( D, A, B, C,  5, 12, 0x4787C62A );
00098     P( C, D, A, B,  6, 17, 0xA8304613 );
00099     P( B, C, D, A,  7, 22, 0xFD469501 );
00100     P( A, B, C, D,  8,  7, 0x698098D8 );
00101     P( D, A, B, C,  9, 12, 0x8B44F7AF );
00102     P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
00103     P( B, C, D, A, 11, 22, 0x895CD7BE );
00104     P( A, B, C, D, 12,  7, 0x6B901122 );
00105     P( D, A, B, C, 13, 12, 0xFD987193 );
00106     P( C, D, A, B, 14, 17, 0xA679438E );
00107     P( B, C, D, A, 15, 22, 0x49B40821 );
00108 
00109 #undef F
00110 
00111 #define F(x,y,z) (y ^ (z & (x ^ y)))
00112 
00113     P( A, B, C, D,  1,  5, 0xF61E2562 );
00114     P( D, A, B, C,  6,  9, 0xC040B340 );
00115     P( C, D, A, B, 11, 14, 0x265E5A51 );
00116     P( B, C, D, A,  0, 20, 0xE9B6C7AA );
00117     P( A, B, C, D,  5,  5, 0xD62F105D );
00118     P( D, A, B, C, 10,  9, 0x02441453 );
00119     P( C, D, A, B, 15, 14, 0xD8A1E681 );
00120     P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
00121     P( A, B, C, D,  9,  5, 0x21E1CDE6 );
00122     P( D, A, B, C, 14,  9, 0xC33707D6 );
00123     P( C, D, A, B,  3, 14, 0xF4D50D87 );
00124     P( B, C, D, A,  8, 20, 0x455A14ED );
00125     P( A, B, C, D, 13,  5, 0xA9E3E905 );
00126     P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
00127     P( C, D, A, B,  7, 14, 0x676F02D9 );
00128     P( B, C, D, A, 12, 20, 0x8D2A4C8A );
00129 
00130 #undef F
00131     
00132 #define F(x,y,z) (x ^ y ^ z)
00133 
00134     P( A, B, C, D,  5,  4, 0xFFFA3942 );
00135     P( D, A, B, C,  8, 11, 0x8771F681 );
00136     P( C, D, A, B, 11, 16, 0x6D9D6122 );
00137     P( B, C, D, A, 14, 23, 0xFDE5380C );
00138     P( A, B, C, D,  1,  4, 0xA4BEEA44 );
00139     P( D, A, B, C,  4, 11, 0x4BDECFA9 );
00140     P( C, D, A, B,  7, 16, 0xF6BB4B60 );
00141     P( B, C, D, A, 10, 23, 0xBEBFBC70 );
00142     P( A, B, C, D, 13,  4, 0x289B7EC6 );
00143     P( D, A, B, C,  0, 11, 0xEAA127FA );
00144     P( C, D, A, B,  3, 16, 0xD4EF3085 );
00145     P( B, C, D, A,  6, 23, 0x04881D05 );
00146     P( A, B, C, D,  9,  4, 0xD9D4D039 );
00147     P( D, A, B, C, 12, 11, 0xE6DB99E5 );
00148     P( C, D, A, B, 15, 16, 0x1FA27CF8 );
00149     P( B, C, D, A,  2, 23, 0xC4AC5665 );
00150 
00151 #undef F
00152 
00153 #define F(x,y,z) (y ^ (x | ~z))
00154 
00155     P( A, B, C, D,  0,  6, 0xF4292244 );
00156     P( D, A, B, C,  7, 10, 0x432AFF97 );
00157     P( C, D, A, B, 14, 15, 0xAB9423A7 );
00158     P( B, C, D, A,  5, 21, 0xFC93A039 );
00159     P( A, B, C, D, 12,  6, 0x655B59C3 );
00160     P( D, A, B, C,  3, 10, 0x8F0CCC92 );
00161     P( C, D, A, B, 10, 15, 0xFFEFF47D );
00162     P( B, C, D, A,  1, 21, 0x85845DD1 );
00163     P( A, B, C, D,  8,  6, 0x6FA87E4F );
00164     P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
00165     P( C, D, A, B,  6, 15, 0xA3014314 );
00166     P( B, C, D, A, 13, 21, 0x4E0811A1 );
00167     P( A, B, C, D,  4,  6, 0xF7537E82 );
00168     P( D, A, B, C, 11, 10, 0xBD3AF235 );
00169     P( C, D, A, B,  2, 15, 0x2AD7D2BB );
00170     P( B, C, D, A,  9, 21, 0xEB86D391 );
00171 
00172 #undef F
00173 
00174     ctx->state[0] += A;
00175     ctx->state[1] += B;
00176     ctx->state[2] += C;
00177     ctx->state[3] += D;
00178 }
00179 
00180 void md5_update( struct md5_context *ctx, uint8 *input, uint32 length )
00181 {
00182     uint32 left, fill;
00183 
00184     if( ! length ) return;
00185 
00186     left = ( ctx->total[0] >> 3 ) & 0x3F;
00187     fill = 64 - left;
00188 
00189     ctx->total[0] += length <<  3;
00190     ctx->total[1] += length >> 29;
00191 
00192     ctx->total[0] &= 0xFFFFFFFF;
00193     ctx->total[1] += ctx->total[0] < length << 3;
00194 
00195     if( left && length >= fill )
00196     {
00197         memcpy( (void *) (ctx->buffer + left), (void *) input, fill );
00198         md5_process( ctx, ctx->buffer );
00199         length -= fill;
00200         input  += fill;
00201         left = 0;
00202     }
00203 
00204     while( length >= 64 )
00205     {
00206         md5_process( ctx, input );
00207         length -= 64;
00208         input  += 64;
00209     }
00210 
00211     if( length )
00212     {
00213         memcpy( (void *) (ctx->buffer + left), (void *) input, length );
00214     }
00215 }
00216 
00217 static uint8 md5_padding[64] =
00218 {
00219  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00220     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00221     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00222     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00223 };
00224 
00225 void md5_finish( struct md5_context *ctx, uint8 digest[16] )
00226 {
00227     uint32 last, padn;
00228     uint8 msglen[8];
00229 
00230     PUT_UINT32( ctx->total[0], msglen, 0 );
00231     PUT_UINT32( ctx->total[1], msglen, 4 );
00232 
00233     last = ( ctx->total[0] >> 3 ) & 0x3F;
00234     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00235 
00236     md5_update( ctx, md5_padding, padn );
00237     md5_update( ctx, msglen, 8 );
00238 
00239     PUT_UINT32( ctx->state[0], digest,  0 );
00240     PUT_UINT32( ctx->state[1], digest,  4 );
00241     PUT_UINT32( ctx->state[2], digest,  8 );
00242     PUT_UINT32( ctx->state[3], digest, 12 );
00243 }
00244 
00245 //---------------------------------------------------------------------------------------------
00246 KStr md5( KStr& sString )
00247 {
00248         md5_context             ctx;
00249         char                    output[33];
00250         unsigned char   md5sum[16];
00251         
00252         md5_starts( &ctx );
00253         md5_update( &ctx, (uint8 *)sString.GetpString(), sString.GetLength() );
00254         md5_finish( &ctx, md5sum );
00255 
00256         for( int j = 0; j < 16; j++ )
00257         {
00258                 sprintf( output + j * 2, "%02x", md5sum[j] );
00259         }
00260 
00261         return KStr( output );
00262 }

Generated on Sun Mar 25 20:02:10 2007 for Zythum Project by  doxygen 1.5.1-p1