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