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;
89 inline void md5_init(md5_state_t *pms);
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
)
107 #define ZSW_MD5_T3 0x242070db
110 #define ZSW_MD5_T6 0x4787c62a
113 #define ZSW_MD5_T9 0x698098d8
117 #define ZSW_MD5_T13 0x6b901122
120 #define ZSW_MD5_T16 0x49b40821
123 #define ZSW_MD5_T19 0x265e5a51
126 #define ZSW_MD5_T22 0x02441453
129 #define ZSW_MD5_T25 0x21e1cde6
132 #define ZSW_MD5_T28 0x455a14ed
135 #define ZSW_MD5_T31 0x676f02d9
139 #define ZSW_MD5_T35 0x6d9d6122
142 #define ZSW_MD5_T38 0x4bdecfa9
145 #define ZSW_MD5_T41 0x289b7ec6
148 #define ZSW_MD5_T44 0x04881d05
151 #define ZSW_MD5_T47 0x1fa27cf8
154 #define ZSW_MD5_T50 0x432aff97
157 #define ZSW_MD5_T53 0x655b59c3
161 #define ZSW_MD5_T57 0x6fa87e4f
164 #define ZSW_MD5_T60 0x4e0811a1
167 #define ZSW_MD5_T63 0x2ad7d2bb
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];
181 md5_word_t
const * X;
191 static int const w = 1;
193 if (*((md5_byte_t
const *)&w))
201 if (!((data - (md5_byte_t
const *)0) & 3)) {
203 X = (md5_word_t
const *)data;
206 std::memcpy(xbuf, data, 64);
220 const md5_byte_t *xp = data;
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)
265 #define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
266 #define SET(a, b, c, d, k, s, Ti)
291 #define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
292 #define SET(a, b, c, d, k, s, Ti)
317 #define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
318 #define SET(a, b, c, d, k, s, Ti)
349 void md5_init(md5_state_t *pms) {
350 pms->count[0] = pms->count[1] = 0;
351 pms->abcd[0] = 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]);