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 #include <iostream>
00064 #include <stdio.h>
00065
00066
00067 MD5::MD5()
00068 {
00069 init();
00070 }
00071
00072
00073
00074
00075
00076 void MD5::update (uint1 *input, uint4 input_length) {
00077
00078 uint4 input_index, buffer_index;
00079 uint4 buffer_space;
00080
00081 if (finalized){
00082 std::cerr << "MD5::update: Can't update a finalized digest!" << std::endl;
00083 return;
00084 }
00085
00086
00087 buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
00088
00089
00090 if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
00091 count[1]++;
00092
00093 count[1] += ((uint4)input_length >> 29);
00094
00095
00096 buffer_space = 64 - buffer_index;
00097
00098
00099 if (input_length >= buffer_space) {
00100
00101 memcpy (buffer + buffer_index, input, buffer_space);
00102 transform (buffer);
00103
00104
00105 for (input_index = buffer_space; input_index + 63 < input_length;
00106 input_index += 64)
00107 transform (input+input_index);
00108
00109 buffer_index = 0;
00110 }
00111 else
00112 input_index=0;
00113
00114
00115
00116 memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
00117 }
00118
00119
00120
00121
00122
00123
00124 void MD5::update(FILE *file){
00125
00126 unsigned char buffer[1024];
00127 int len;
00128
00129 while (true)
00130 {
00131 len=fread(buffer, 1, 1024, file);
00132 if(!len)
00133 { break; }
00134
00135 update(buffer, len);
00136 }
00137
00138 fclose (file);
00139
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 void MD5::update(std::istream& stream){
00151
00152 unsigned char buffer[1024];
00153 int len;
00154
00155 while (stream.good()){
00156 stream.read((char*)buffer, 1024);
00157 len=stream.gcount();
00158 update(buffer, len);
00159 }
00160
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 void MD5::update(std::ifstream& stream){
00172
00173 unsigned char buffer[1024];
00174 int len;
00175
00176 while (stream.good()){
00177 stream.read((char*)buffer, 1024);
00178 len=stream.gcount();
00179 update(buffer, len);
00180 }
00181
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 void MD5::finalize (){
00194
00195 unsigned char bits[8];
00196 unsigned int index, padLen;
00197 static uint1 PADDING[64]={
00198 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00201 };
00202
00203 if (finalized){
00204 std::cerr << "MD5::finalize: Already finalized this digest!" << std::endl;
00205 return;
00206 }
00207
00208
00209 encode (bits, count, 8);
00210
00211
00212 index = (uint4) ((count[0] >> 3) & 0x3f);
00213 padLen = (index < 56) ? (56 - index) : (120 - index);
00214 update (PADDING, padLen);
00215
00216
00217 update (bits, 8);
00218
00219
00220 encode (digest, state, 16);
00221
00222
00223 memset (buffer, 0, sizeof(*buffer));
00224
00225 finalized=1;
00226
00227 }
00228
00229
00230
00231
00232 MD5::MD5(FILE *file){
00233
00234 init();
00235 update(file);
00236 finalize ();
00237 }
00238
00239
00240
00241
00242 MD5::MD5(std::istream& stream){
00243
00244 init();
00245 update (stream);
00246 finalize();
00247 }
00248
00249
00250
00251 MD5::MD5(std::ifstream& stream){
00252
00253 init();
00254 update (stream);
00255 finalize();
00256 }
00257
00258
00259
00260 unsigned char *MD5::raw_digest(){
00261
00262 uint1 *s = new uint1[16];
00263
00264 if (!finalized){
00265 std::cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
00266 "finalized the digest!" << std::endl;
00267 return ( (unsigned char*) "");
00268 }
00269
00270 memcpy(s, digest, 16);
00271 return s;
00272 }
00273
00274
00275
00276 QString MD5::hex_digest(){
00277
00278 int i;
00279 char *s= new char[33];
00280
00281 if (!finalized){
00282 std::cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
00283 "finalized the digest!" << std::endl;
00284 return "";
00285 }
00286
00287 for (i=0; i<16; i++)
00288 sprintf(s+i*2, "%02x", digest[i]);
00289
00290 s[32]='\0';
00291
00292 QString result(s);
00293 delete s;
00294 return result;
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 }
00545
00546
00547 QString getMD5(std::ifstream& stream)
00548 {
00549 MD5 obj( stream );
00550 return obj.hex_digest();
00551 }
00552
00553
00554 bool filesMatch(std::ifstream& stream, QString oldMD5)
00555 {
00556 MD5 obj( stream );
00557 return (obj.hex_digest() == oldMD5);
00558 }
00559