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