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