57 #ifndef WEBSOCKETPP_COMMON_MD5_HPP 58 #define WEBSOCKETPP_COMMON_MD5_HPP 78 typedef unsigned char md5_byte_t;
79 typedef unsigned int md5_word_t;
92 inline void md5_append(
md5_state_t *pms, md5_byte_t
const * data,
size_t nbytes);
95 inline 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) 170 static 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);
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;
357 void 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);
393 void 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));
415 inline 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());
431 const char hexval[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
433 inline 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]);
448 #endif // WEBSOCKETPP_COMMON_MD5_HPP
Namespace for the WebSocket++ project.