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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "md5.hh"
00049
00050 #include <assert.h>
00051 #include <string>
00052 #include <iostream>
00053
00054
00055
00056
00057
00058
00059 _MD5::_MD5(){
00060
00061 init();
00062
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072 void _MD5::update (uint1 *input, uint4 input_length) {
00073
00074 uint4 input_index, buffer_index;
00075 uint4 buffer_space;
00076
00077 if (finalized){
00078 cerr << "_MD5::update: Can't update a finalized digest!" << endl;
00079 return;
00080 }
00081
00082
00083 buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
00084
00085
00086 if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
00087 count[1]++;
00088
00089 count[1] += ((uint4)input_length >> 29);
00090
00091
00092 buffer_space = 64 - buffer_index;
00093
00094
00095 if (input_length >= buffer_space) {
00096
00097 memcpy (buffer + buffer_index, input, buffer_space);
00098 transform (buffer);
00099
00100
00101 for (input_index = buffer_space; input_index + 63 < input_length;
00102 input_index += 64)
00103 transform (input+input_index);
00104
00105 buffer_index = 0;
00106 }
00107 else
00108 input_index=0;
00109
00110
00111
00112 memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
00113 }
00114
00115
00116
00117
00118
00119
00120 void _MD5::update(FILE *file){
00121
00122 unsigned char buffer[1024];
00123 int len;
00124
00125 while (len=fread(buffer, 1, 1024, file))
00126 update(buffer, len);
00127
00128 fclose (file);
00129
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 void _MD5::update(istream& stream){
00141
00142 unsigned char buffer[1024];
00143 int len;
00144
00145 while (stream.good()){
00146 stream.read((char*)buffer, 1024);
00147 len=stream.gcount();
00148 update(buffer, len);
00149 }
00150
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 void _MD5::update(ifstream& stream){
00162
00163 unsigned char buffer[1024];
00164 int len;
00165
00166 while (stream.good()){
00167 stream.read((char*)buffer, 1024);
00168 len=stream.gcount();
00169 update(buffer, len);
00170 }
00171
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 void _MD5::finalize (){
00184
00185 unsigned char bits[8];
00186 unsigned int index, padLen;
00187 static uint1 PADDING[64]={
00188 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00191 };
00192
00193 if (finalized){
00194 cerr << "_MD5::finalize: Already finalized this digest!" << endl;
00195 return;
00196 }
00197
00198
00199 encode (bits, count, 8);
00200
00201
00202 index = (uint4) ((count[0] >> 3) & 0x3f);
00203 padLen = (index < 56) ? (56 - index) : (120 - index);
00204 update (PADDING, padLen);
00205
00206
00207 update (bits, 8);
00208
00209
00210 encode (digest, state, 16);
00211
00212
00213 memset (buffer, 0, sizeof(*buffer));
00214
00215 finalized=1;
00216
00217 }
00218
00219
00220
00221
00222 _MD5::_MD5(FILE *file){
00223
00224 init();
00225 update(file);
00226 finalize ();
00227 }
00228
00229
00230
00231
00232 _MD5::_MD5(istream& stream){
00233
00234 init();
00235 update (stream);
00236 finalize();
00237 }
00238
00239
00240
00241 _MD5::_MD5(ifstream& stream){
00242
00243 init();
00244 update (stream);
00245 finalize();
00246 }
00247
00248
00249
00250 unsigned char *_MD5::raw_digest(){
00251
00252 uint1 *s = new uint1[16];
00253
00254 if (!finalized){
00255 cerr << "_MD5::raw_digest: Can't get digest if you haven't "<<
00256 "finalized the digest!" <<endl;
00257 return ( (unsigned char*) "");
00258 }
00259
00260 memcpy(s, digest, 16);
00261 return s;
00262 }
00263
00264
00265
00266 char *_MD5::hex_digest(){
00267
00268 int i;
00269 char *s= new char[33];
00270
00271 if (!finalized){
00272 cerr << "_MD5::hex_digest: Can't get digest if you haven't "<<
00273 "finalized the digest!" <<endl;
00274 return "";
00275 }
00276
00277 for (i=0; i<16; i++)
00278 sprintf(s+i*2, "%02x", digest[i]);
00279
00280 s[32]='\0';
00281
00282 return s;
00283 }
00284
00285
00286
00287
00288
00289 ostream& operator<<(ostream &stream, _MD5 context){
00290
00291 stream << context.hex_digest();
00292 return stream;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302 void _MD5::init(){
00303 finalized=0;
00304
00305
00306 count[0] = 0;
00307 count[1] = 0;
00308
00309
00310 state[0] = 0x67452301;
00311 state[1] = 0xefcdab89;
00312 state[2] = 0x98badcfe;
00313 state[3] = 0x10325476;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 #define S11 7
00323 #define S12 12
00324 #define S13 17
00325 #define S14 22
00326 #define S21 5
00327 #define S22 9
00328 #define S23 14
00329 #define S24 20
00330 #define S31 4
00331 #define S32 11
00332 #define S33 16
00333 #define S34 23
00334 #define S41 6
00335 #define S42 10
00336 #define S43 15
00337 #define S44 21
00338
00339
00340
00341
00342
00343 void _MD5::transform (uint1 block[64]){
00344
00345 uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00346
00347 decode (x, block, 64);
00348
00349 assert(!finalized);
00350
00351
00352 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
00353 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
00354 FF (c, d, a, b, x[ 2], S13, 0x242070db);
00355 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
00356 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
00357 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
00358 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
00359 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
00360 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
00361 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
00362 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
00363 FF (b, c, d, a, x[11], S14, 0x895cd7be);
00364 FF (a, b, c, d, x[12], S11, 0x6b901122);
00365 FF (d, a, b, c, x[13], S12, 0xfd987193);
00366 FF (c, d, a, b, x[14], S13, 0xa679438e);
00367 FF (b, c, d, a, x[15], S14, 0x49b40821);
00368
00369
00370 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
00371 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
00372 GG (c, d, a, b, x[11], S23, 0x265e5a51);
00373 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
00374 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
00375 GG (d, a, b, c, x[10], S22, 0x2441453);
00376 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
00377 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
00378 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
00379 GG (d, a, b, c, x[14], S22, 0xc33707d6);
00380 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
00381 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
00382 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
00383 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
00384 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
00385 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
00386
00387
00388 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
00389 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
00390 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
00391 HH (b, c, d, a, x[14], S34, 0xfde5380c);
00392 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
00393 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
00394 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
00395 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
00396 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
00397 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
00398 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
00399 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
00400 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
00401 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
00402 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
00403 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
00404
00405
00406 II (a, b, c, d, x[ 0], S41, 0xf4292244);
00407 II (d, a, b, c, x[ 7], S42, 0x432aff97);
00408 II (c, d, a, b, x[14], S43, 0xab9423a7);
00409 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
00410 II (a, b, c, d, x[12], S41, 0x655b59c3);
00411 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
00412 II (c, d, a, b, x[10], S43, 0xffeff47d);
00413 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
00414 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
00415 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
00416 II (c, d, a, b, x[ 6], S43, 0xa3014314);
00417 II (b, c, d, a, x[13], S44, 0x4e0811a1);
00418 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
00419 II (d, a, b, c, x[11], S42, 0xbd3af235);
00420 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
00421 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
00422
00423 state[0] += a;
00424 state[1] += b;
00425 state[2] += c;
00426 state[3] += d;
00427
00428
00429 memset ( (uint1 *) x, 0, sizeof(x));
00430
00431 }
00432
00433
00434
00435
00436
00437 void _MD5::encode (uint1 *output, uint4 *input, uint4 len) {
00438
00439 unsigned int i, j;
00440
00441 for (i = 0, j = 0; j < len; i++, j += 4) {
00442 output[j] = (uint1) (input[i] & 0xff);
00443 output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
00444 output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
00445 output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
00446 }
00447 }
00448
00449
00450
00451
00452
00453
00454 void _MD5::decode (uint4 *output, uint1 *input, uint4 len){
00455
00456 unsigned int i, j;
00457
00458 for (i = 0, j = 0; j < len; i++, j += 4)
00459 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
00460 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
00461 }
00462
00463
00464
00465
00466
00467
00468 void _MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
00469
00470 unsigned int i;
00471
00472 for (i = 0; i < len; i++)
00473 output[i] = input[i];
00474 }
00475
00476
00477
00478
00479 void _MD5::memset (uint1 *output, uint1 value, uint4 len){
00480
00481 unsigned int i;
00482
00483 for (i = 0; i < len; i++)
00484 output[i] = value;
00485 }
00486
00487
00488
00489
00490
00491 inline unsigned int _MD5::rotate_left (uint4 x, uint4 n){
00492 return (x << n) | (x >> (32-n)) ;
00493 }
00494
00495
00496
00497
00498
00499
00500 inline unsigned int _MD5::F (uint4 x, uint4 y, uint4 z){
00501 return (x & y) | (~x & z);
00502 }
00503
00504 inline unsigned int _MD5::G (uint4 x, uint4 y, uint4 z){
00505 return (x & z) | (y & ~z);
00506 }
00507
00508 inline unsigned int _MD5::H (uint4 x, uint4 y, uint4 z){
00509 return x ^ y ^ z;
00510 }
00511
00512 inline unsigned int _MD5::I (uint4 x, uint4 y, uint4 z){
00513 return y ^ (x | ~z);
00514 }
00515
00516
00517
00518
00519
00520
00521
00522 inline void _MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00523 uint4 s, uint4 ac){
00524 a += F(b, c, d) + x + ac;
00525 a = rotate_left (a, s) +b;
00526 }
00527
00528 inline void _MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00529 uint4 s, uint4 ac){
00530 a += G(b, c, d) + x + ac;
00531 a = rotate_left (a, s) +b;
00532 }
00533
00534 inline void _MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00535 uint4 s, uint4 ac){
00536 a += H(b, c, d) + x + ac;
00537 a = rotate_left (a, s) +b;
00538 }
00539
00540 inline void _MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00541 uint4 s, uint4 ac){
00542 a += I(b, c, d) + x + ac;
00543 a = rotate_left (a, s) +b;
00544 }