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 #include <cassert>
00043 #include <string>
00044 #include <cstdio>
00045 #include <cstring>
00046 #include <iostream>
00047
00048 using namespace std;
00049
00050
00051
00052
00053 #define S11 7
00054 #define S12 12
00055 #define S13 17
00056 #define S14 22
00057 #define S21 5
00058 #define S22 9
00059 #define S23 14
00060 #define S24 20
00061 #define S31 4
00062 #define S32 11
00063 #define S33 16
00064 #define S34 23
00065 #define S41 6
00066 #define S42 10
00067 #define S43 15
00068 #define S44 21
00069
00070 namespace {
00071 class MD5 {
00072 public:
00074 MD5 (unsigned char* buffer, unsigned long len);
00076 MD5 ();
00078 void update (unsigned char *input, unsigned int input_length);
00079
00080 void finalize ();
00081
00083
00084 void raw_digest (unsigned char *buff);
00085
00087 string hex_digest ();
00089
00090 private:
00091
00092 unsigned int state[4];
00093 unsigned int count[2];
00094 unsigned char buffer[64];
00095 unsigned char digest[16];
00096 unsigned char finalized;
00097
00098
00099 void init ();
00100 void transform (unsigned char *buffer);
00101
00102
00103 static void encode (unsigned char *dest, unsigned int *src, unsigned int length);
00104 static void decode (unsigned int *dest, unsigned char *src, unsigned int length);
00105
00106
00107 static inline unsigned int rotate_left (unsigned int x, unsigned int n)
00108 { return (x << n) | (x >> (32-n)); }
00109
00110 static inline unsigned int F(unsigned int x, unsigned int y, unsigned int z)
00111 { return (x & y) | (~x & z); }
00112 static inline unsigned int G(unsigned int x, unsigned int y, unsigned int z)
00113 { return (x & z) | (y & ~z); }
00114 static inline unsigned int H(unsigned int x, unsigned int y, unsigned int z)
00115 { return x ^ y ^ z; }
00116 static inline unsigned int I(unsigned int x, unsigned int y, unsigned int z)
00117 { return y ^ (x | ~z); }
00118
00119
00120
00121 static inline void FF (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00122 {
00123 a += F(b, c, d) + x + ac;
00124 a = rotate_left(a, s) + b;
00125 }
00126 static inline void GG (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00127 {
00128 a += G(b, c, d) + x + ac;
00129 a = rotate_left(a, s) + b;
00130 }
00131 static inline void HH (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00132 {
00133 a += H(b, c, d) + x + ac;
00134 a = rotate_left(a, s) + b;
00135 }
00136 static inline void II (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00137 {
00138 a += I(b, c, d) + x + ac;
00139 a = rotate_left(a, s) + b;
00140 }
00141 };
00142 }
00143
00144
00145 MD5::MD5() {
00146 init();
00147 }
00148
00149
00150 MD5::MD5(unsigned char* buffer, unsigned long len) {
00151 init();
00152 update(buffer, len);
00153 finalize();
00154 }
00155
00156
00157
00158
00159 void MD5::update (unsigned char *input, unsigned int input_length) {
00160 unsigned int idx, index, space;
00161 if ( finalized ) {
00162 cerr << "MD5::update: Can't update a finalized digest!" << endl;
00163 return;
00164 }
00165
00166 index = (unsigned int)((count[0] >> 3) & 0x3F);
00167
00168 if ( (count[0] += ((unsigned int) input_length << 3))<((unsigned int) input_length << 3) )
00169 count[1]++;
00170
00171 count[1] += ((unsigned int)input_length >> 29);
00172 space = 64 - index;
00173
00174 if (input_length >= space) {
00175
00176 memcpy (buffer + index, input, space);
00177 transform (buffer);
00178
00179 for (idx = space; idx + 63 < input_length; idx += 64)
00180 transform (input+idx);
00181
00182 index = 0;
00183 }
00184 else {
00185 idx = 0;
00186 }
00187
00188
00189 memcpy(buffer+index, input+idx, input_length-idx);
00190 }
00191
00192
00193
00194 void MD5::finalize () {
00195 unsigned char bits[8];
00196 unsigned int index, padLen;
00197 static unsigned char 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 if (finalized){
00203 cerr << "MD5::finalize: Already finalized this digest!" << endl;
00204 return;
00205 }
00206
00207 encode (bits, count, 8);
00208
00209 index = (unsigned int) ((count[0] >> 3) & 0x3f);
00210 padLen = (index < 56) ? (56 - index) : (120 - index);
00211 update (PADDING, padLen);
00212
00213 update (bits, 8);
00214
00215 encode (digest, state, 16);
00216
00217 memset (buffer, 0, sizeof(*buffer));
00218 finalized=1;
00219 }
00220
00222 void MD5::raw_digest(unsigned char *s){
00223 if (finalized){
00224 memcpy(s, digest, 16);
00225 return;
00226 }
00227 cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
00228 "finalized the digest!" << endl;
00229 }
00230
00231 string MD5::hex_digest() {
00232 char s[33];
00233 if (!finalized){
00234 cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
00235 "finalized the digest!" <<endl;
00236 return "";
00237 }
00238 for (int i=0; i<16; i++)
00239 sprintf(s+i*2, "%02x", digest[i]);
00240 s[32]='\0';
00241 return s;
00242 }
00243
00244
00245 void MD5::init(){
00246 finalized=0;
00247
00248 count[0] = 0;
00249 count[1] = 0;
00250
00251 state[0] = 0x67452301;
00252 state[1] = 0xefcdab89;
00253 state[2] = 0x98badcfe;
00254 state[3] = 0x10325476;
00255 }
00256
00257
00258 void MD5::transform (unsigned char* block){
00259 unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00260 decode (x, block, 64);
00261 assert(!finalized);
00262
00263 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
00264 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
00265 FF (c, d, a, b, x[ 2], S13, 0x242070db);
00266 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
00267 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
00268 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
00269 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
00270 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
00271 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
00272 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
00273 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
00274 FF (b, c, d, a, x[11], S14, 0x895cd7be);
00275 FF (a, b, c, d, x[12], S11, 0x6b901122);
00276 FF (d, a, b, c, x[13], S12, 0xfd987193);
00277 FF (c, d, a, b, x[14], S13, 0xa679438e);
00278 FF (b, c, d, a, x[15], S14, 0x49b40821);
00279
00280 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
00281 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
00282 GG (c, d, a, b, x[11], S23, 0x265e5a51);
00283 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
00284 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
00285 GG (d, a, b, c, x[10], S22, 0x2441453);
00286 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
00287 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
00288 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
00289 GG (d, a, b, c, x[14], S22, 0xc33707d6);
00290 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
00291 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
00292 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
00293 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
00294 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
00295 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
00296
00297 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
00298 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
00299 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
00300 HH (b, c, d, a, x[14], S34, 0xfde5380c);
00301 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
00302 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
00303 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
00304 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
00305 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
00306 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
00307 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
00308 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
00309 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
00310 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
00311 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
00312 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
00313
00314 II (a, b, c, d, x[ 0], S41, 0xf4292244);
00315 II (d, a, b, c, x[ 7], S42, 0x432aff97);
00316 II (c, d, a, b, x[14], S43, 0xab9423a7);
00317 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
00318 II (a, b, c, d, x[12], S41, 0x655b59c3);
00319 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
00320 II (c, d, a, b, x[10], S43, 0xffeff47d);
00321 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
00322 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
00323 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
00324 II (c, d, a, b, x[ 6], S43, 0xa3014314);
00325 II (b, c, d, a, x[13], S44, 0x4e0811a1);
00326 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
00327 II (d, a, b, c, x[11], S42, 0xbd3af235);
00328 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
00329 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
00330 state[0] += a;
00331 state[1] += b;
00332 state[2] += c;
00333 state[3] += d;
00334
00335 memset ( (unsigned char *) x, 0, sizeof(x));
00336 }
00337
00338
00339
00340 void MD5::encode (unsigned char *output, unsigned int *input, unsigned int len) {
00341 for (unsigned int i = 0, j = 0; j < len; i++, j += 4) {
00342 output[j] = (unsigned char) (input[i] & 0xff);
00343 output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff);
00344 output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff);
00345 output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff);
00346 }
00347 }
00348
00349
00350
00351 void MD5::decode (unsigned int *output, unsigned char *input, unsigned int len){
00352 for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
00353 output[i] = ((unsigned int)input[j]) | (((unsigned int)input[j+1]) << 8) |
00354 (((unsigned int)input[j+2]) << 16) | (((unsigned int)input[j+3]) << 24);
00355 }
00356
00357 namespace cond {
00358 void* genMD5(void* buffer, unsigned long len, void* code) {
00359 MD5 checkSum((unsigned char*)buffer, len);
00360 checkSum.raw_digest((unsigned char*)code);
00361 return code;
00362 }
00363 void genMD5(const string& s, void* code) {
00364 MD5 checkSum((unsigned char*)s.c_str(), s.length());
00365 checkSum.raw_digest((unsigned char*)code);
00366 }
00367 }