78typedef unsigned char md5_byte_t;
79typedef unsigned int md5_word_t;
92inline void md5_append(
md5_state_t *pms, md5_byte_t
const * data,
size_t nbytes);
95inline void md5_finish(
md5_state_t *pms, md5_byte_t digest[16]);
97#undef ZSW_MD5_BYTE_ORDER
98#ifdef ARCH_IS_BIG_ENDIAN
99# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
101# define ZSW_MD5_BYTE_ORDER 0
104#define ZSW_MD5_T_MASK ((md5_word_t)~0)
105#define ZSW_MD5_T1 (ZSW_MD5_T_MASK ^ 0x28955b87)
106#define ZSW_MD5_T2 (ZSW_MD5_T_MASK ^ 0x173848a9)
107#define ZSW_MD5_T3 0x242070db
108#define ZSW_MD5_T4 (ZSW_MD5_T_MASK ^ 0x3e423111)
109#define ZSW_MD5_T5 (ZSW_MD5_T_MASK ^ 0x0a83f050)
110#define ZSW_MD5_T6 0x4787c62a
111#define ZSW_MD5_T7 (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
112#define ZSW_MD5_T8 (ZSW_MD5_T_MASK ^ 0x02b96afe)
113#define ZSW_MD5_T9 0x698098d8
114#define ZSW_MD5_T10 (ZSW_MD5_T_MASK ^ 0x74bb0850)
115#define ZSW_MD5_T11 (ZSW_MD5_T_MASK ^ 0x0000a44e)
116#define ZSW_MD5_T12 (ZSW_MD5_T_MASK ^ 0x76a32841)
117#define ZSW_MD5_T13 0x6b901122
118#define ZSW_MD5_T14 (ZSW_MD5_T_MASK ^ 0x02678e6c)
119#define ZSW_MD5_T15 (ZSW_MD5_T_MASK ^ 0x5986bc71)
120#define ZSW_MD5_T16 0x49b40821
121#define ZSW_MD5_T17 (ZSW_MD5_T_MASK ^ 0x09e1da9d)
122#define ZSW_MD5_T18 (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
123#define ZSW_MD5_T19 0x265e5a51
124#define ZSW_MD5_T20 (ZSW_MD5_T_MASK ^ 0x16493855)
125#define ZSW_MD5_T21 (ZSW_MD5_T_MASK ^ 0x29d0efa2)
126#define ZSW_MD5_T22 0x02441453
127#define ZSW_MD5_T23 (ZSW_MD5_T_MASK ^ 0x275e197e)
128#define ZSW_MD5_T24 (ZSW_MD5_T_MASK ^ 0x182c0437)
129#define ZSW_MD5_T25 0x21e1cde6
130#define ZSW_MD5_T26 (ZSW_MD5_T_MASK ^ 0x3cc8f829)
131#define ZSW_MD5_T27 (ZSW_MD5_T_MASK ^ 0x0b2af278)
132#define ZSW_MD5_T28 0x455a14ed
133#define ZSW_MD5_T29 (ZSW_MD5_T_MASK ^ 0x561c16fa)
134#define ZSW_MD5_T30 (ZSW_MD5_T_MASK ^ 0x03105c07)
135#define ZSW_MD5_T31 0x676f02d9
136#define ZSW_MD5_T32 (ZSW_MD5_T_MASK ^ 0x72d5b375)
137#define ZSW_MD5_T33 (ZSW_MD5_T_MASK ^ 0x0005c6bd)
138#define ZSW_MD5_T34 (ZSW_MD5_T_MASK ^ 0x788e097e)
139#define ZSW_MD5_T35 0x6d9d6122
140#define ZSW_MD5_T36 (ZSW_MD5_T_MASK ^ 0x021ac7f3)
141#define ZSW_MD5_T37 (ZSW_MD5_T_MASK ^ 0x5b4115bb)
142#define ZSW_MD5_T38 0x4bdecfa9
143#define ZSW_MD5_T39 (ZSW_MD5_T_MASK ^ 0x0944b49f)
144#define ZSW_MD5_T40 (ZSW_MD5_T_MASK ^ 0x4140438f)
145#define ZSW_MD5_T41 0x289b7ec6
146#define ZSW_MD5_T42 (ZSW_MD5_T_MASK ^ 0x155ed805)
147#define ZSW_MD5_T43 (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
148#define ZSW_MD5_T44 0x04881d05
149#define ZSW_MD5_T45 (ZSW_MD5_T_MASK ^ 0x262b2fc6)
150#define ZSW_MD5_T46 (ZSW_MD5_T_MASK ^ 0x1924661a)
151#define ZSW_MD5_T47 0x1fa27cf8
152#define ZSW_MD5_T48 (ZSW_MD5_T_MASK ^ 0x3b53a99a)
153#define ZSW_MD5_T49 (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
154#define ZSW_MD5_T50 0x432aff97
155#define ZSW_MD5_T51 (ZSW_MD5_T_MASK ^ 0x546bdc58)
156#define ZSW_MD5_T52 (ZSW_MD5_T_MASK ^ 0x036c5fc6)
157#define ZSW_MD5_T53 0x655b59c3
158#define ZSW_MD5_T54 (ZSW_MD5_T_MASK ^ 0x70f3336d)
159#define ZSW_MD5_T55 (ZSW_MD5_T_MASK ^ 0x00100b82)
160#define ZSW_MD5_T56 (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
161#define ZSW_MD5_T57 0x6fa87e4f
162#define ZSW_MD5_T58 (ZSW_MD5_T_MASK ^ 0x01d3191f)
163#define ZSW_MD5_T59 (ZSW_MD5_T_MASK ^ 0x5cfebceb)
164#define ZSW_MD5_T60 0x4e0811a1
165#define ZSW_MD5_T61 (ZSW_MD5_T_MASK ^ 0x08ac817d)
166#define ZSW_MD5_T62 (ZSW_MD5_T_MASK ^ 0x42c50dca)
167#define ZSW_MD5_T63 0x2ad7d2bb
168#define ZSW_MD5_T64 (ZSW_MD5_T_MASK ^ 0x14792c6e)
170static void md5_process(
md5_state_t *pms, md5_byte_t
const * data ) {
172 a = pms->abcd[0], b = pms->abcd[1],
173 c = pms->abcd[2], d = pms->abcd[3];
175#if ZSW_MD5_BYTE_ORDER > 0
181 md5_word_t
const * X;
185#if ZSW_MD5_BYTE_ORDER == 0
191 static int const w = 1;
193 if (*((md5_byte_t
const *)&w))
195#if ZSW_MD5_BYTE_ORDER <= 0
201 if (!((data - (md5_byte_t
const *)0) & 3)) {
203 X = (md5_word_t
const *)data;
206 std::memcpy(xbuf, data, 64);
211#if ZSW_MD5_BYTE_ORDER == 0
214#if ZSW_MD5_BYTE_ORDER >= 0
220 const md5_byte_t *xp = data;
223# if ZSW_MD5_BYTE_ORDER == 0
228 for (i = 0; i < 16; ++i, xp += 4)
229 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
234#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
239#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
240#define SET(a, b, c, d, k, s, Ti)\
241 t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
242 a = ZSW_MD5_ROTATE_LEFT(t, s) + b
244 SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
245 SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
246 SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
247 SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
248 SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
249 SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
250 SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
251 SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
252 SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
253 SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
254 SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
255 SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
256 SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
257 SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
258 SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
259 SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
265#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
266#define SET(a, b, c, d, k, s, Ti)\
267 t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
268 a = ZSW_MD5_ROTATE_LEFT(t, s) + b
270 SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
271 SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
272 SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
273 SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
274 SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
275 SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
276 SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
277 SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
278 SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
279 SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
280 SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
281 SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
282 SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
283 SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
284 SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
285 SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
291#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
292#define SET(a, b, c, d, k, s, Ti)\
293 t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
294 a = ZSW_MD5_ROTATE_LEFT(t, s) + b
296 SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
297 SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
298 SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
299 SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
300 SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
301 SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
302 SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
303 SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
304 SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
305 SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
306 SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
307 SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
308 SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
309 SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
310 SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
311 SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
317#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
318#define SET(a, b, c, d, k, s, Ti)\
319 t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
320 a = ZSW_MD5_ROTATE_LEFT(t, s) + b
322 SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
323 SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
324 SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
325 SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
326 SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
327 SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
328 SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
329 SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
330 SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
331 SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
332 SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
333 SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
334 SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
335 SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
336 SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
337 SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
349void md5_init(md5_state_t *pms) {
350 pms->count[0] = pms->count[1] = 0;
351 pms->abcd[0] = 0x67452301;
352 pms->abcd[1] = ZSW_MD5_T_MASK ^ 0x10325476;
353 pms->abcd[2] = ZSW_MD5_T_MASK ^ 0x67452301;
354 pms->abcd[3] = 0x10325476;
357void md5_append(md5_state_t *pms, md5_byte_t
const * data,
size_t nbytes) {
358 md5_byte_t
const * p = data;
359 size_t left = nbytes;
360 int offset = (pms->count[0] >> 3) & 63;
361 md5_word_t nbits = (md5_word_t)(nbytes << 3);
367 pms->count[1] += nbytes >> 29;
368 pms->count[0] += nbits;
369 if (pms->count[0] < nbits)
374 int copy = (offset + nbytes > 64 ? 64 - offset :
static_cast<int>(nbytes));
376 std::memcpy(pms->buf + offset, p, copy);
377 if (offset + copy < 64)
381 md5_process(pms, pms->buf);
385 for (; left >= 64; p += 64, left -= 64)
390 std::memcpy(pms->buf, p, left);
393void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
394 static md5_byte_t
const pad[64] = {
395 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
404 for (i = 0; i < 8; ++i)
405 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
407 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
409 md5_append(pms, data, 8);
410 for (i = 0; i < 16; ++i)
411 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
415inline std::string md5_hash_string(std::string
const & s) {
421 md5_append(&state, (md5_byte_t
const *)s.c_str(), s.size());
422 md5_finish(&state, (md5_byte_t *)digest);
426 std::copy(digest,digest+16,ret.begin());
431const char hexval[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
433inline std::string md5_hash_hex(std::string
const & input) {
434 std::string hash = md5_hash_string(input);
437 for (
size_t i = 0; i < hash.size(); i++) {
438 hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
439 hex.push_back(hexval[(hash[i]) & 0x0F]);