1
+ #include " md5.h"
2
+ #include < cstdio>
3
+
4
+ #define S11 7
5
+ #define S12 12
6
+ #define S13 17
7
+ #define S14 22
8
+ #define S21 5
9
+ #define S22 9
10
+ #define S23 14
11
+ #define S24 20
12
+ #define S31 4
13
+ #define S32 11
14
+ #define S33 16
15
+ #define S34 23
16
+ #define S41 6
17
+ #define S42 10
18
+ #define S43 15
19
+ #define S44 21
20
+
21
+ inline MD5::uint4 MD5::F (uint4 x, uint4 y, uint4 z) {
22
+ return x&y | ~x&z;
23
+ }
24
+
25
+ inline MD5::uint4 MD5::G (uint4 x, uint4 y, uint4 z) {
26
+ return x&z | y&~z;
27
+ }
28
+
29
+ inline MD5::uint4 MD5::H (uint4 x, uint4 y, uint4 z) {
30
+ return x^y^z;
31
+ }
32
+
33
+ inline MD5::uint4 MD5::I (uint4 x, uint4 y, uint4 z) {
34
+ return y ^ (x | ~z);
35
+ }
36
+
37
+ inline MD5::uint4 MD5::rotate_left (uint4 x, int n) {
38
+ return (x << n) | (x >> (32 -n));
39
+ }
40
+
41
+ inline void MD5::FF (uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
42
+ a = rotate_left (a+ F (b,c,d) + x + ac, s) + b;
43
+ }
44
+
45
+ inline void MD5::GG (uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
46
+ a = rotate_left (a + G (b,c,d) + x + ac, s) + b;
47
+ }
48
+
49
+ inline void MD5::HH (uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
50
+ a = rotate_left (a + H (b,c,d) + x + ac, s) + b;
51
+ }
52
+
53
+ inline void MD5::II (uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
54
+ a = rotate_left (a + I (b,c,d) + x + ac, s) + b;
55
+ }
56
+
57
+ MD5::MD5 () {
58
+ init ();
59
+ }
60
+
61
+ MD5::MD5 (const std::string &text) {
62
+ init ();
63
+ update (text.c_str (), text.length ());
64
+ finalize ();
65
+ }
66
+
67
+ void MD5::init () {
68
+ finalized=false ;
69
+
70
+ count[0 ] = 0 ;
71
+ count[1 ] = 0 ;
72
+
73
+ state[0 ] = 0x67452301 ;
74
+ state[1 ] = 0xefcdab89 ;
75
+ state[2 ] = 0x98badcfe ;
76
+ state[3 ] = 0x10325476 ;
77
+ }
78
+
79
+ void MD5::decode (uint4 output[], const uint1 input[], size_type len) {
80
+ for (unsigned int i = 0 , j = 0 ; j < len; i++, j += 4 )
81
+ output[i] = ((uint4)input[j]) | (((uint4)input[j+1 ]) << 8 ) |
82
+ (((uint4)input[j+2 ]) << 16 ) | (((uint4)input[j+3 ]) << 24 );
83
+ }
84
+
85
+ void MD5::encode (uint1 output[], const uint4 input[], size_type len) {
86
+ for (size_type i = 0 , j = 0 ; j < len; i++, j += 4 ) {
87
+ output[j] = input[i] & 0xff ;
88
+ output[j+1 ] = (input[i] >> 8 ) & 0xff ;
89
+ output[j+2 ] = (input[i] >> 16 ) & 0xff ;
90
+ output[j+3 ] = (input[i] >> 24 ) & 0xff ;
91
+ }
92
+ }
93
+
94
+ void MD5::transform (const uint1 block[blocksize]) {
95
+ uint4 a = state[0 ], b = state[1 ], c = state[2 ], d = state[3 ], x[16 ];
96
+ decode (x, block, blocksize);
97
+
98
+ FF (a, b, c, d, x[ 0 ], S11, 0xd76aa478 ); /* 1 */
99
+ FF (d, a, b, c, x[ 1 ], S12, 0xe8c7b756 ); /* 2 */
100
+ FF (c, d, a, b, x[ 2 ], S13, 0x242070db ); /* 3 */
101
+ FF (b, c, d, a, x[ 3 ], S14, 0xc1bdceee ); /* 4 */
102
+ FF (a, b, c, d, x[ 4 ], S11, 0xf57c0faf ); /* 5 */
103
+ FF (d, a, b, c, x[ 5 ], S12, 0x4787c62a ); /* 6 */
104
+ FF (c, d, a, b, x[ 6 ], S13, 0xa8304613 ); /* 7 */
105
+ FF (b, c, d, a, x[ 7 ], S14, 0xfd469501 ); /* 8 */
106
+ FF (a, b, c, d, x[ 8 ], S11, 0x698098d8 ); /* 9 */
107
+ FF (d, a, b, c, x[ 9 ], S12, 0x8b44f7af ); /* 10 */
108
+ FF (c, d, a, b, x[10 ], S13, 0xffff5bb1 ); /* 11 */
109
+ FF (b, c, d, a, x[11 ], S14, 0x895cd7be ); /* 12 */
110
+ FF (a, b, c, d, x[12 ], S11, 0x6b901122 ); /* 13 */
111
+ FF (d, a, b, c, x[13 ], S12, 0xfd987193 ); /* 14 */
112
+ FF (c, d, a, b, x[14 ], S13, 0xa679438e ); /* 15 */
113
+ FF (b, c, d, a, x[15 ], S14, 0x49b40821 ); /* 16 */
114
+
115
+ GG (a, b, c, d, x[ 1 ], S21, 0xf61e2562 ); /* 17 */
116
+ GG (d, a, b, c, x[ 6 ], S22, 0xc040b340 ); /* 18 */
117
+ GG (c, d, a, b, x[11 ], S23, 0x265e5a51 ); /* 19 */
118
+ GG (b, c, d, a, x[ 0 ], S24, 0xe9b6c7aa ); /* 20 */
119
+ GG (a, b, c, d, x[ 5 ], S21, 0xd62f105d ); /* 21 */
120
+ GG (d, a, b, c, x[10 ], S22, 0x2441453 ); /* 22 */
121
+ GG (c, d, a, b, x[15 ], S23, 0xd8a1e681 ); /* 23 */
122
+ GG (b, c, d, a, x[ 4 ], S24, 0xe7d3fbc8 ); /* 24 */
123
+ GG (a, b, c, d, x[ 9 ], S21, 0x21e1cde6 ); /* 25 */
124
+ GG (d, a, b, c, x[14 ], S22, 0xc33707d6 ); /* 26 */
125
+ GG (c, d, a, b, x[ 3 ], S23, 0xf4d50d87 ); /* 27 */
126
+ GG (b, c, d, a, x[ 8 ], S24, 0x455a14ed ); /* 28 */
127
+ GG (a, b, c, d, x[13 ], S21, 0xa9e3e905 ); /* 29 */
128
+ GG (d, a, b, c, x[ 2 ], S22, 0xfcefa3f8 ); /* 30 */
129
+ GG (c, d, a, b, x[ 7 ], S23, 0x676f02d9 ); /* 31 */
130
+ GG (b, c, d, a, x[12 ], S24, 0x8d2a4c8a ); /* 32 */
131
+
132
+ HH (a, b, c, d, x[ 5 ], S31, 0xfffa3942 ); /* 33 */
133
+ HH (d, a, b, c, x[ 8 ], S32, 0x8771f681 ); /* 34 */
134
+ HH (c, d, a, b, x[11 ], S33, 0x6d9d6122 ); /* 35 */
135
+ HH (b, c, d, a, x[14 ], S34, 0xfde5380c ); /* 36 */
136
+ HH (a, b, c, d, x[ 1 ], S31, 0xa4beea44 ); /* 37 */
137
+ HH (d, a, b, c, x[ 4 ], S32, 0x4bdecfa9 ); /* 38 */
138
+ HH (c, d, a, b, x[ 7 ], S33, 0xf6bb4b60 ); /* 39 */
139
+ HH (b, c, d, a, x[10 ], S34, 0xbebfbc70 ); /* 40 */
140
+ HH (a, b, c, d, x[13 ], S31, 0x289b7ec6 ); /* 41 */
141
+ HH (d, a, b, c, x[ 0 ], S32, 0xeaa127fa ); /* 42 */
142
+ HH (c, d, a, b, x[ 3 ], S33, 0xd4ef3085 ); /* 43 */
143
+ HH (b, c, d, a, x[ 6 ], S34, 0x4881d05 ); /* 44 */
144
+ HH (a, b, c, d, x[ 9 ], S31, 0xd9d4d039 ); /* 45 */
145
+ HH (d, a, b, c, x[12 ], S32, 0xe6db99e5 ); /* 46 */
146
+ HH (c, d, a, b, x[15 ], S33, 0x1fa27cf8 ); /* 47 */
147
+ HH (b, c, d, a, x[ 2 ], S34, 0xc4ac5665 ); /* 48 */
148
+
149
+ II (a, b, c, d, x[ 0 ], S41, 0xf4292244 ); /* 49 */
150
+ II (d, a, b, c, x[ 7 ], S42, 0x432aff97 ); /* 50 */
151
+ II (c, d, a, b, x[14 ], S43, 0xab9423a7 ); /* 51 */
152
+ II (b, c, d, a, x[ 5 ], S44, 0xfc93a039 ); /* 52 */
153
+ II (a, b, c, d, x[12 ], S41, 0x655b59c3 ); /* 53 */
154
+ II (d, a, b, c, x[ 3 ], S42, 0x8f0ccc92 ); /* 54 */
155
+ II (c, d, a, b, x[10 ], S43, 0xffeff47d ); /* 55 */
156
+ II (b, c, d, a, x[ 1 ], S44, 0x85845dd1 ); /* 56 */
157
+ II (a, b, c, d, x[ 8 ], S41, 0x6fa87e4f ); /* 57 */
158
+ II (d, a, b, c, x[15 ], S42, 0xfe2ce6e0 ); /* 58 */
159
+ II (c, d, a, b, x[ 6 ], S43, 0xa3014314 ); /* 59 */
160
+ II (b, c, d, a, x[13 ], S44, 0x4e0811a1 ); /* 60 */
161
+ II (a, b, c, d, x[ 4 ], S41, 0xf7537e82 ); /* 61 */
162
+ II (d, a, b, c, x[11 ], S42, 0xbd3af235 ); /* 62 */
163
+ II (c, d, a, b, x[ 2 ], S43, 0x2ad7d2bb ); /* 63 */
164
+ II (b, c, d, a, x[ 9 ], S44, 0xeb86d391 ); /* 64 */
165
+
166
+ state[0 ] += a;
167
+ state[1 ] += b;
168
+ state[2 ] += c;
169
+ state[3 ] += d;
170
+
171
+ memset (x, 0 , sizeof x);
172
+ }
173
+
174
+ void MD5::update (const unsigned char input[], size_type length) {
175
+ size_type index = count[0 ] / 8 % blocksize;
176
+
177
+ if ((count[0 ] += (length << 3 )) < (length << 3 ))
178
+ count[1 ]++;
179
+ count[1 ] += (length >> 29 );
180
+
181
+ size_type firstpart = 64 - index;
182
+ size_type i;
183
+
184
+ if (length >= firstpart) {
185
+ memcpy (&buffer[index], input, firstpart);
186
+ transform (buffer);
187
+
188
+ for (i = firstpart; i + blocksize <= length; i += blocksize)
189
+ transform (&input[i]);
190
+
191
+ index = 0 ;
192
+ }
193
+ else
194
+ i = 0 ;
195
+
196
+ memcpy (&buffer[index], &input[i], length-i);
197
+ }
198
+
199
+ void MD5::update (const char input[], size_type length) {
200
+ update ((const unsigned char *)input, length);
201
+ }
202
+
203
+ MD5& MD5::finalize () {
204
+ static unsigned char padding[64 ] = {
205
+ 0x80 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
206
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
207
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
208
+ };
209
+
210
+ if (!finalized) {
211
+ unsigned char bits[8 ];
212
+ encode (bits, count, 8 );
213
+
214
+ size_type index = count[0 ] / 8 % 64 ;
215
+ size_type padLen = (index < 56 ) ? (56 - index) : (120 - index);
216
+ update (padding, padLen);
217
+
218
+ update (bits, 8 );
219
+
220
+ encode (digest, state, 16 );
221
+
222
+ memset (buffer, 0 , sizeof buffer);
223
+ memset (count, 0 , sizeof count);
224
+
225
+ finalized=true ;
226
+ }
227
+
228
+ return *this ;
229
+ }
230
+
231
+ std::string MD5::hexdigest () const {
232
+ if (!finalized)
233
+ return " " ;
234
+
235
+ char buf[33 ];
236
+ for (int i=0 ; i<16 ; i++)
237
+ sprintf (buf+i*2 , " %02x" , digest[i]);
238
+ buf[32 ]=0 ;
239
+
240
+ return std::string (buf);
241
+ }
242
+
243
+ std::ostream& operator <<(std::ostream& out, MD5 md5) {
244
+ return out << md5.hexdigest ();
245
+ }
246
+
247
+ std::string md5 (const std::string str) {
248
+ MD5 md5 = MD5 (str);
249
+
250
+ return md5.hexdigest ();
251
+ }
0 commit comments