Warning, file /include/rsa/md5.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef BZF_MD5_H
0036 #define BZF_MD5_H
0037
0038 #include <cstring>
0039 #include <iostream>
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 class MD5
0053 {
0054 public:
0055 typedef unsigned int size_type;
0056
0057 MD5();
0058 MD5(const std::string& text);
0059 void update(const unsigned char *buf, size_type length);
0060 void update(const char *buf, size_type length);
0061 MD5& finalize();
0062 std::string hexdigest() const;
0063 friend std::ostream& operator<<(std::ostream&, MD5 md5);
0064
0065 private:
0066 void init();
0067 typedef unsigned char uint1;
0068 typedef unsigned int uint4;
0069 enum {blocksize = 64};
0070
0071 void transform(const uint1 block[blocksize]);
0072 static void decode(uint4 output[], const uint1 input[], size_type len);
0073 static void encode(uint1 output[], const uint4 input[], size_type len);
0074
0075 bool finalized;
0076 uint1 buffer[blocksize];
0077 uint4 count[2];
0078 uint4 state[4];
0079 uint1 digest[16];
0080
0081
0082 static inline uint4 F(uint4 x, uint4 y, uint4 z);
0083 static inline uint4 G(uint4 x, uint4 y, uint4 z);
0084 static inline uint4 H(uint4 x, uint4 y, uint4 z);
0085 static inline uint4 I(uint4 x, uint4 y, uint4 z);
0086 static inline uint4 rotate_left(uint4 x, int n);
0087 static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
0088 static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
0089 static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
0090 static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
0091 };
0092
0093 std::string md5(const std::string str);
0094
0095 #endif
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 #include <cstdio>
0135
0136
0137
0138 #define S11 7
0139 #define S12 12
0140 #define S13 17
0141 #define S14 22
0142 #define S21 5
0143 #define S22 9
0144 #define S23 14
0145 #define S24 20
0146 #define S31 4
0147 #define S32 11
0148 #define S33 16
0149 #define S34 23
0150 #define S41 6
0151 #define S42 10
0152 #define S43 15
0153 #define S44 21
0154
0155
0156
0157
0158 inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
0159 return (x&y) | (~x&z);
0160 }
0161
0162 inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
0163 return (x&z) | (y&~z);
0164 }
0165
0166 inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
0167 return x^y^z;
0168 }
0169
0170 inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
0171 return y ^ (x | ~z);
0172 }
0173
0174
0175 inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
0176 return (x << n) | (x >> (32-n));
0177 }
0178
0179
0180
0181 inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
0182 a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
0183 }
0184
0185 inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
0186 a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
0187 }
0188
0189 inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
0190 a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
0191 }
0192
0193 inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
0194 a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
0195 }
0196
0197
0198
0199
0200 MD5::MD5()
0201 {
0202 init();
0203 }
0204
0205
0206
0207
0208 MD5::MD5(const std::string &text)
0209 {
0210 init();
0211 update(text.c_str(), text.length());
0212 finalize();
0213 }
0214
0215
0216
0217 void MD5::init()
0218 {
0219 finalized=false;
0220
0221 count[0] = 0;
0222 count[1] = 0;
0223
0224
0225 state[0] = 0x67452301;
0226 state[1] = 0xefcdab89;
0227 state[2] = 0x98badcfe;
0228 state[3] = 0x10325476;
0229 }
0230
0231
0232
0233
0234 void MD5::decode(uint4 output[], const uint1 input[], size_type len)
0235 {
0236 for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
0237 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
0238 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
0239 }
0240
0241
0242
0243
0244
0245 void MD5::encode(uint1 output[], const uint4 input[], size_type len)
0246 {
0247 for (size_type i = 0, j = 0; j < len; i++, j += 4) {
0248 output[j] = input[i] & 0xff;
0249 output[j+1] = (input[i] >> 8) & 0xff;
0250 output[j+2] = (input[i] >> 16) & 0xff;
0251 output[j+3] = (input[i] >> 24) & 0xff;
0252 }
0253 }
0254
0255
0256
0257
0258 void MD5::transform(const uint1 block[blocksize])
0259 {
0260 uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
0261 decode (x, block, blocksize);
0262
0263
0264 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
0265 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
0266 FF (c, d, a, b, x[ 2], S13, 0x242070db);
0267 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
0268 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
0269 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
0270 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
0271 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
0272 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
0273 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
0274 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
0275 FF (b, c, d, a, x[11], S14, 0x895cd7be);
0276 FF (a, b, c, d, x[12], S11, 0x6b901122);
0277 FF (d, a, b, c, x[13], S12, 0xfd987193);
0278 FF (c, d, a, b, x[14], S13, 0xa679438e);
0279 FF (b, c, d, a, x[15], S14, 0x49b40821);
0280
0281
0282 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
0283 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
0284 GG (c, d, a, b, x[11], S23, 0x265e5a51);
0285 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
0286 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
0287 GG (d, a, b, c, x[10], S22, 0x2441453);
0288 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
0289 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
0290 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
0291 GG (d, a, b, c, x[14], S22, 0xc33707d6);
0292 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
0293 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
0294 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
0295 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
0296 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
0297 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
0298
0299
0300 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
0301 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
0302 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
0303 HH (b, c, d, a, x[14], S34, 0xfde5380c);
0304 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
0305 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
0306 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
0307 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
0308 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
0309 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
0310 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
0311 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
0312 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
0313 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
0314 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
0315 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
0316
0317
0318 II (a, b, c, d, x[ 0], S41, 0xf4292244);
0319 II (d, a, b, c, x[ 7], S42, 0x432aff97);
0320 II (c, d, a, b, x[14], S43, 0xab9423a7);
0321 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
0322 II (a, b, c, d, x[12], S41, 0x655b59c3);
0323 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
0324 II (c, d, a, b, x[10], S43, 0xffeff47d);
0325 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
0326 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
0327 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
0328 II (c, d, a, b, x[ 6], S43, 0xa3014314);
0329 II (b, c, d, a, x[13], S44, 0x4e0811a1);
0330 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
0331 II (d, a, b, c, x[11], S42, 0xbd3af235);
0332 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
0333 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
0334
0335 state[0] += a;
0336 state[1] += b;
0337 state[2] += c;
0338 state[3] += d;
0339
0340
0341 memset(x, 0, sizeof x);
0342 }
0343
0344
0345
0346
0347
0348 void MD5::update(const unsigned char input[], size_type length)
0349 {
0350
0351 size_type index = count[0] / 8 % blocksize;
0352
0353
0354 if ((count[0] += (length << 3)) < (length << 3))
0355 count[1]++;
0356 count[1] += (length >> 29);
0357
0358
0359 size_type firstpart = 64 - index;
0360
0361 size_type i;
0362
0363
0364 if (length >= firstpart)
0365 {
0366
0367 memcpy(&buffer[index], input, firstpart);
0368 transform(buffer);
0369
0370
0371 for (i = firstpart; i + blocksize <= length; i += blocksize)
0372 transform(&input[i]);
0373
0374 index = 0;
0375 }
0376 else
0377 i = 0;
0378
0379
0380 memcpy(&buffer[index], &input[i], length-i);
0381 }
0382
0383
0384
0385
0386 void MD5::update(const char input[], size_type length)
0387 {
0388 update((const unsigned char*)input, length);
0389 }
0390
0391
0392
0393
0394
0395 MD5& MD5::finalize()
0396 {
0397 static unsigned char padding[64] = {
0398 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0401 };
0402
0403 if (!finalized) {
0404
0405 unsigned char bits[8];
0406 encode(bits, count, 8);
0407
0408
0409 size_type index = count[0] / 8 % 64;
0410 size_type padLen = (index < 56) ? (56 - index) : (120 - index);
0411 update(padding, padLen);
0412
0413
0414 update(bits, 8);
0415
0416
0417 encode(digest, state, 16);
0418
0419
0420 memset(buffer, 0, sizeof buffer);
0421 memset(count, 0, sizeof count);
0422
0423 finalized=true;
0424 }
0425
0426 return *this;
0427 }
0428
0429
0430
0431
0432 std::string MD5::hexdigest() const
0433 {
0434 if (!finalized)
0435 return "";
0436
0437 char buf[33];
0438 for (int i=0; i<16; i++)
0439 sprintf(buf+i*2, "%02x", digest[i]);
0440 buf[32]=0;
0441
0442 return std::string(buf);
0443 }
0444
0445
0446
0447 std::ostream& operator<<(std::ostream& out, MD5 md5)
0448 {
0449 return out << md5.hexdigest();
0450 }
0451
0452
0453
0454 std::string md5(const std::string str)
0455 {
0456 MD5 md5 = MD5(str);
0457
0458 return md5.hexdigest();
0459 }