25#ifndef TIMEMORY_UTILITY_MD5_CPP_
26#define TIMEMORY_UTILITY_MD5_CPP_ 1
31#if !defined(TIMEMORY_UTILITY_HEADER_MODE)
47constexpr uint32_t S11 = 7;
48constexpr uint32_t S12 = 12;
49constexpr uint32_t S13 = 17;
50constexpr uint32_t S14 = 22;
51constexpr uint32_t S21 = 5;
52constexpr uint32_t S22 = 9;
53constexpr uint32_t S23 = 14;
54constexpr uint32_t S24 = 20;
55constexpr uint32_t S31 = 4;
56constexpr uint32_t S32 = 11;
57constexpr uint32_t S33 = 16;
58constexpr uint32_t S34 = 23;
59constexpr uint32_t S41 = 6;
60constexpr uint32_t S42 = 10;
61constexpr uint32_t S43 = 15;
62constexpr uint32_t S44 = 21;
66F(uint32_t x, uint32_t y, uint32_t z);
69G(uint32_t x, uint32_t y, uint32_t z);
72H(uint32_t x, uint32_t y, uint32_t z);
75I(uint32_t x, uint32_t y, uint32_t z);
78rotate_left(uint32_t x,
int n);
81FF(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
84GG(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
87HH(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
90II(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
94F(uint32_t x, uint32_t y, uint32_t z)
96 return (x & y) | (~x & z);
100G(uint32_t x, uint32_t y, uint32_t z)
102 return (x & z) | (y & ~z);
106H(uint32_t x, uint32_t y, uint32_t z)
112I(uint32_t x, uint32_t y, uint32_t z)
119rotate_left(uint32_t x,
int n)
121 return (x << n) | (x >> (32 - n));
127FF(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
129 a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
133GG(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
135 a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
139HH(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
141 a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
145II(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
147 a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
154decode(uint32_t* output,
const uint8_t* input, size_type len)
156 for(
unsigned int i = 0, j = 0; j < len; i++, j += 4)
157 output[i] = ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) |
158 (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
166encode(uint8_t* output,
const uint32_t* input, size_type len)
168 for(size_type i = 0, j = 0; j < len; i++, j += 4)
170 output[j] = input[i] & 0xff;
171 output[j + 1] = (input[i] >> 8) & 0xff;
172 output[j + 2] = (input[i] >> 16) & 0xff;
173 output[j + 3] = (input[i] >> 24) & 0xff;
187 update(text.c_str(), text.length());
196md5sum::transform(
const uint8_t block[blocksize])
198 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
202 FF(a, b, c, d, x[0], S11, 0xd76aa478);
203 FF(d, a, b, c, x[1], S12, 0xe8c7b756);
204 FF(c, d, a, b, x[2], S13, 0x242070db);
205 FF(b, c, d, a, x[3], S14, 0xc1bdceee);
206 FF(a, b, c, d, x[4], S11, 0xf57c0faf);
207 FF(d, a, b, c, x[5], S12, 0x4787c62a);
208 FF(c, d, a, b, x[6], S13, 0xa8304613);
209 FF(b, c, d, a, x[7], S14, 0xfd469501);
210 FF(a, b, c, d, x[8], S11, 0x698098d8);
211 FF(d, a, b, c, x[9], S12, 0x8b44f7af);
212 FF(c, d, a, b, x[10], S13, 0xffff5bb1);
213 FF(b, c, d, a, x[11], S14, 0x895cd7be);
214 FF(a, b, c, d, x[12], S11, 0x6b901122);
215 FF(d, a, b, c, x[13], S12, 0xfd987193);
216 FF(c, d, a, b, x[14], S13, 0xa679438e);
217 FF(b, c, d, a, x[15], S14, 0x49b40821);
220 GG(a, b, c, d, x[1], S21, 0xf61e2562);
221 GG(d, a, b, c, x[6], S22, 0xc040b340);
222 GG(c, d, a, b, x[11], S23, 0x265e5a51);
223 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);
224 GG(a, b, c, d, x[5], S21, 0xd62f105d);
225 GG(d, a, b, c, x[10], S22, 0x2441453);
226 GG(c, d, a, b, x[15], S23, 0xd8a1e681);
227 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);
228 GG(a, b, c, d, x[9], S21, 0x21e1cde6);
229 GG(d, a, b, c, x[14], S22, 0xc33707d6);
230 GG(c, d, a, b, x[3], S23, 0xf4d50d87);
231 GG(b, c, d, a, x[8], S24, 0x455a14ed);
232 GG(a, b, c, d, x[13], S21, 0xa9e3e905);
233 GG(d, a, b, c, x[2], S22, 0xfcefa3f8);
234 GG(c, d, a, b, x[7], S23, 0x676f02d9);
235 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);
238 HH(a, b, c, d, x[5], S31, 0xfffa3942);
239 HH(d, a, b, c, x[8], S32, 0x8771f681);
240 HH(c, d, a, b, x[11], S33, 0x6d9d6122);
241 HH(b, c, d, a, x[14], S34, 0xfde5380c);
242 HH(a, b, c, d, x[1], S31, 0xa4beea44);
243 HH(d, a, b, c, x[4], S32, 0x4bdecfa9);
244 HH(c, d, a, b, x[7], S33, 0xf6bb4b60);
245 HH(b, c, d, a, x[10], S34, 0xbebfbc70);
246 HH(a, b, c, d, x[13], S31, 0x289b7ec6);
247 HH(d, a, b, c, x[0], S32, 0xeaa127fa);
248 HH(c, d, a, b, x[3], S33, 0xd4ef3085);
249 HH(b, c, d, a, x[6], S34, 0x4881d05);
250 HH(a, b, c, d, x[9], S31, 0xd9d4d039);
251 HH(d, a, b, c, x[12], S32, 0xe6db99e5);
252 HH(c, d, a, b, x[15], S33, 0x1fa27cf8);
253 HH(b, c, d, a, x[2], S34, 0xc4ac5665);
256 II(a, b, c, d, x[0], S41, 0xf4292244);
257 II(d, a, b, c, x[7], S42, 0x432aff97);
258 II(c, d, a, b, x[14], S43, 0xab9423a7);
259 II(b, c, d, a, x[5], S44, 0xfc93a039);
260 II(a, b, c, d, x[12], S41, 0x655b59c3);
261 II(d, a, b, c, x[3], S42, 0x8f0ccc92);
262 II(c, d, a, b, x[10], S43, 0xffeff47d);
263 II(b, c, d, a, x[1], S44, 0x85845dd1);
264 II(a, b, c, d, x[8], S41, 0x6fa87e4f);
265 II(d, a, b, c, x[15], S42, 0xfe2ce6e0);
266 II(c, d, a, b, x[6], S43, 0xa3014314);
267 II(b, c, d, a, x[13], S44, 0x4e0811a1);
268 II(a, b, c, d, x[4], S41, 0xf7537e82);
269 II(d, a, b, c, x[11], S42, 0xbd3af235);
270 II(c, d, a, b, x[2], S43, 0x2ad7d2bb);
271 II(b, c, d, a, x[9], S44, 0xeb86d391);
279 memset(x, 0,
sizeof x);
294 if((count[0] += (length << 3)) < (length << 3))
296 count[1] += (length >> 29);
303 if(length >= firstpart)
306 memcpy(&buffer[index], input, firstpart);
307 transform(buffer.data());
311 transform(&input[i]);
317 memcpy(&buffer[index], &input[i], length - i);
329 return update((
const unsigned char*) input, length);
340 static unsigned char padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
349 unsigned char bits[8];
350 encode(bits, count.data(), 8);
354 size_type padLen = (index < 56) ? (56 - index) : (120 - index);
361 encode(digest.data(), state.data(), 16);
364 memset(buffer.data(), 0,
sizeof buffer);
365 memset(count.data(), 0,
sizeof count);
384 for(
int i = 0; i < 16; i++)
385 sprintf(buf + i * 2,
"%02x", digest[i]);
md5sum & update(const unsigned char *buf, size_type length)
std::string hexdigest() const
static constexpr int blocksize
TIMEMORY_UTILITY_INLINE std::string compute_md5(const std::string &inp)
TIMEMORY_UTILITY_INLINE std::ostream & operator<<(std::ostream &out, md5sum md5)
tim::mpl::apply< std::string > string
#define TIMEMORY_UTILITY_INLINE