31 #ifndef _CRT_SECURE_NO_DEPRECATE
32 #define _CRT_SECURE_NO_DEPRECATE 1
44 static const char mb64_charset[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
50 #define GET_UINT32_LE(n,b,i) \
52 (n) = ( (unsigned long) (b)[(i) ] ) \
53 | ( (unsigned long) (b)[(i) + 1] << 8 ) \
54 | ( (unsigned long) (b)[(i) + 2] << 16 ) \
55 | ( (unsigned long) (b)[(i) + 3] << 24 ); \
59 #define PUT_UINT32_LE(n,b,i) \
61 (b)[(i) ] = (unsigned char) ( (n) ); \
62 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
63 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
64 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
76 ctx->
state[0] = 0x67452301;
77 ctx->
state[1] = 0xEFCDAB89;
78 ctx->
state[2] = 0x98BADCFE;
79 ctx->
state[3] = 0x10325476;
84 unsigned long X[16], A, B, C, D;
103 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
105 #define P(a,b,c,d,k,s,t) \
107 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
115 #define F(x,y,z) (z ^ (x & (y ^ z)))
117 P( A, B, C, D, 0, 7, 0xD76AA478 );
118 P( D, A, B, C, 1, 12, 0xE8C7B756 );
119 P( C, D, A, B, 2, 17, 0x242070DB );
120 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
121 P( A, B, C, D, 4, 7, 0xF57C0FAF );
122 P( D, A, B, C, 5, 12, 0x4787C62A );
123 P( C, D, A, B, 6, 17, 0xA8304613 );
124 P( B, C, D, A, 7, 22, 0xFD469501 );
125 P( A, B, C, D, 8, 7, 0x698098D8 );
126 P( D, A, B, C, 9, 12, 0x8B44F7AF );
127 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
128 P( B, C, D, A, 11, 22, 0x895CD7BE );
129 P( A, B, C, D, 12, 7, 0x6B901122 );
130 P( D, A, B, C, 13, 12, 0xFD987193 );
131 P( C, D, A, B, 14, 17, 0xA679438E );
132 P( B, C, D, A, 15, 22, 0x49B40821 );
136 #define F(x,y,z) (y ^ (z & (x ^ y)))
138 P( A, B, C, D, 1, 5, 0xF61E2562 );
139 P( D, A, B, C, 6, 9, 0xC040B340 );
140 P( C, D, A, B, 11, 14, 0x265E5A51 );
141 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
142 P( A, B, C, D, 5, 5, 0xD62F105D );
143 P( D, A, B, C, 10, 9, 0x02441453 );
144 P( C, D, A, B, 15, 14, 0xD8A1E681 );
145 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
146 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
147 P( D, A, B, C, 14, 9, 0xC33707D6 );
148 P( C, D, A, B, 3, 14, 0xF4D50D87 );
149 P( B, C, D, A, 8, 20, 0x455A14ED );
150 P( A, B, C, D, 13, 5, 0xA9E3E905 );
151 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
152 P( C, D, A, B, 7, 14, 0x676F02D9 );
153 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
157 #define F(x,y,z) (x ^ y ^ z)
159 P( A, B, C, D, 5, 4, 0xFFFA3942 );
160 P( D, A, B, C, 8, 11, 0x8771F681 );
161 P( C, D, A, B, 11, 16, 0x6D9D6122 );
162 P( B, C, D, A, 14, 23, 0xFDE5380C );
163 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
164 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
165 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
166 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
167 P( A, B, C, D, 13, 4, 0x289B7EC6 );
168 P( D, A, B, C, 0, 11, 0xEAA127FA );
169 P( C, D, A, B, 3, 16, 0xD4EF3085 );
170 P( B, C, D, A, 6, 23, 0x04881D05 );
171 P( A, B, C, D, 9, 4, 0xD9D4D039 );
172 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
173 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
174 P( B, C, D, A, 2, 23, 0xC4AC5665 );
178 #define F(x,y,z) (y ^ (x | ~z))
180 P( A, B, C, D, 0, 6, 0xF4292244 );
181 P( D, A, B, C, 7, 10, 0x432AFF97 );
182 P( C, D, A, B, 14, 15, 0xAB9423A7 );
183 P( B, C, D, A, 5, 21, 0xFC93A039 );
184 P( A, B, C, D, 12, 6, 0x655B59C3 );
185 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
186 P( C, D, A, B, 10, 15, 0xFFEFF47D );
187 P( B, C, D, A, 1, 21, 0x85845DD1 );
188 P( A, B, C, D, 8, 6, 0x6FA87E4F );
189 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
190 P( C, D, A, B, 6, 15, 0xA3014314 );
191 P( B, C, D, A, 13, 21, 0x4E0811A1 );
192 P( A, B, C, D, 4, 6, 0xF7537E82 );
193 P( D, A, B, C, 11, 10, 0xBD3AF235 );
194 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
195 P( B, C, D, A, 9, 21, 0xEB86D391 );
216 left = ctx->
total[0] & 0x3F;
219 ctx->
total[0] += ilen;
220 ctx->
total[0] &= 0xFFFFFFFF;
222 if( ctx->
total[0] < (
unsigned long) ilen )
225 if( left && ilen >= fill )
227 memcpy( (
void *) (ctx->
buffer + left),
228 (
void *) input, fill );
244 memcpy( (
void *) (ctx->
buffer + left),
245 (
void *) input, ilen );
251 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
262 unsigned long last, padn;
263 unsigned long high, low;
264 unsigned char msglen[8];
266 high = ( ctx->
total[0] >> 29 )
267 | ( ctx->
total[1] << 3 );
268 low = ( ctx->
total[0] << 3 );
273 last = ctx->
total[0] & 0x3F;
274 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
288 int md5_file(
char *path,
unsigned char output[16] )
293 unsigned char buf[1024];
295 if( ( f = fopen( path,
"rb" ) ) == NULL )
300 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
312 void md5_csum(
const unsigned char *input,
int ilen,
313 unsigned char output[16] )
326 const unsigned char *input,
int ilen,
327 unsigned char output[16] )
331 unsigned char k_ipad[64];
332 unsigned char k_opad[64];
333 unsigned char tmpbuf[16];
335 memset( k_ipad, 0x36, 64 );
336 memset( k_opad, 0x5C, 64 );
338 for( i = 0; i < keylen; i++ )
356 memset( k_ipad, 0, 64 );
357 memset( k_opad, 0, 64 );
358 memset( tmpbuf, 0, 16 );
366 void md5_hex(
const void *input,
size_t len,
char output[33]) {
368 unsigned char digest[16];
371 md5_update(&ctx, (
const unsigned char *)input, len);
375 for (
int i=0; i<16; i++) {
376 index = (digest[i] & 0xF0) >> 4;
378 index = digest[i] & 0x0F;
385 md5_hex(input, strlen(input), output);
390 unsigned char digest[16];
394 md5_update(&ctx, (
const unsigned char *)input, strlen(input));
397 memcpy(&hash, digest,
sizeof(int64_t));
406 while (digest_pos < 12) {
408 output[output_pos] = (digest[digest_pos] & 0xfc) >> 2;
409 output[output_pos+1] = ((digest[digest_pos] & 0x03) << 4) |
410 ((digest[digest_pos+1] & 0xf0) >> 4);
411 output[output_pos+2] = ((digest[digest_pos+1] & 0x0f) << 2) |
412 ((digest[digest_pos+2] & 0xc0) >> 6);
413 output[output_pos+3] = digest[digest_pos+2] & 0x3f;
416 for(
int ii=0; ii<4; ++ii)
417 output[output_pos+ii] =
mb64_charset[(
unsigned)output[output_pos+ii]];
427 unsigned char digest[16];
428 size_t len = strlen(input);
431 md5_update(&ctx, (
const unsigned char *)input, len);
447 {
"message digest" },
448 {
"abcdefghijklmnopqrstuvwxyz" },
449 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
450 {
"12345678901234567890123456789012345678901234567890123456789012" \
451 "345678901234567890" }
456 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
457 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
458 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
459 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
460 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
461 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
462 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
463 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
464 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
465 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
466 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
467 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
468 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
469 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
479 unsigned char md5sum[16];
481 for( i = 0; i < 7; i++ )
483 printf(
" MD5 test #%d: ", i + 1 );
490 printf(
"failed\n" );
494 printf(
"passed\n" );
void md5_hmac(unsigned char *key, int keylen, const unsigned char *input, int ilen, unsigned char output[16])
Calculates a "Hashed MAC" of an input buffer combined with a secret key.
int64_t md5_hash(const char *input)
Returns a 64-bit hash checksum of a null terminated input buffer.
static const char md5_test_str[7][81]
void digest_to_trunc_modified_base64(const char digest[16], char output[17])
Get the modified base64 encoded string of a 16 byte message digest see http://en.wikipedia.org/wiki/Base64#URL_applications for more information.
void md5_trunc_modified_base64(const char *input, char output[17])
Get the modified base64 encoded string of the first 12 Bytes of the 16 Byte MD5 code of a null termin...
void md5_update(md5_context *ctx, const unsigned char *input, int ilen)
Adds data to the MD5 process buffer.
void md5_starts(md5_context *ctx)
Initialize and setup a MD5 context structure.
static const unsigned char md5_padding[64]
void md5_csum(const unsigned char *input, int ilen, unsigned char output[16])
Convenience function to calculate the MD5 sum of an input buffer.
static void md5_process(md5_context *ctx, const unsigned char data[64])
void md5_string(const char *input, char output[33])
Calculates the hex string of MD5 of null terminated input.
static const char hex_digits[]
MD5 context structure; this structure is used to store the internal state of the md5 algorithm...
static const unsigned char md5_test_sum[7][16]
#define P(a, b, c, d, k, s, t)
void md5_finish(md5_context *ctx, unsigned char output[16])
Retrieve the final MD5 digest.
int md5_self_test(void)
Runs a self test.
#define GET_UINT32_LE(n, b, i)
void md5_hex(const void *input, size_t len, char output[33])
Convenience function to calculate the MD5 sum of an input buffer; returns string with the MD5 encoded...
#define PUT_UINT32_LE(n, b, i)
int md5_file(char *path, unsigned char output[16])
static const char _md5_src[]
static const char mb64_charset[]