标签:
代码从polarssl中扒来的,略作改动,md5.h & md5.cpp 如下
1 #ifndef POLARSSL_MD5_H 2 #define POLARSSL_MD5_H 3 4 #include <string> 5 #include <stdint.h> 6 7 class md5 8 { 9 public: 10 void string_md5(const unsigned char *input, size_t ilen, unsigned char output[16]); 11 12 // open file failed return -1; 13 int file_md5(const char *path, unsigned char output[16]); 14 15 private: 16 typedef struct 17 { 18 uint32_t total[2]; /*!< number of bytes processed */ 19 uint32_t state[4]; /*!< intermediate digest state */ 20 unsigned char buffer[64]; /*!< data block being processed */ 21 22 unsigned char ipad[64]; /*!< HMAC: inner padding */ 23 unsigned char opad[64]; /*!< HMAC: outer padding */ 24 } 25 md5_context; 26 27 void md5_init(md5_context *ctx); 28 29 void md5_free(md5_context *ctx); 30 31 void md5_starts(md5_context *ctx); 32 33 void md5_update(md5_context *ctx, const unsigned char *input, size_t ilen); 34 35 void md5_finish(md5_context *ctx, unsigned char output[16]); 36 37 void md5_process(md5_context *ctx, const unsigned char data[64]); 38 }; 39 40 #endif // POLARSSL_MD5_H
1 #include "md5.h" 2 #include <stdio.h> 3 4 /* 5 * 32-bit integer manipulation macros (little endian) 6 */ 7 #ifndef GET_UINT32_LE 8 #define GET_UINT32_LE(n,b,i) 9 { 10 (n) = ( (uint32_t) (b)[(i) ] ) 11 | ( (uint32_t) (b)[(i) + 1] << 8 ) 12 | ( (uint32_t) (b)[(i) + 2] << 16 ) 13 | ( (uint32_t) (b)[(i) + 3] << 24 ); 14 } 15 #endif 16 17 #ifndef PUT_UINT32_LE 18 #define PUT_UINT32_LE(n,b,i) 19 { 20 (b)[(i) ] = (unsigned char) ( (n) ); 21 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); 22 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); 23 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); 24 } 25 #endif 26 27 void md5::md5_init(md5_context *ctx) 28 { 29 memset(ctx, 0, sizeof(md5_context)); 30 } 31 32 void md5::md5_free(md5_context *ctx) 33 { 34 if (ctx == NULL) 35 return; 36 37 size_t n = sizeof(md5_context); 38 volatile unsigned char *p = (unsigned char*)ctx; while (n--) *p++ = 0; 39 } 40 41 /* 42 * MD5 context setup 43 */ 44 void md5::md5_starts(md5_context *ctx) 45 { 46 ctx->total[0] = 0; 47 ctx->total[1] = 0; 48 49 ctx->state[0] = 0x67452301; 50 ctx->state[1] = 0xEFCDAB89; 51 ctx->state[2] = 0x98BADCFE; 52 ctx->state[3] = 0x10325476; 53 } 54 55 void md5::md5_process(md5_context *ctx, const unsigned char data[64]) 56 { 57 uint32_t X[16], A, B, C, D; 58 59 GET_UINT32_LE(X[0], data, 0); 60 GET_UINT32_LE(X[1], data, 4); 61 GET_UINT32_LE(X[2], data, 8); 62 GET_UINT32_LE(X[3], data, 12); 63 GET_UINT32_LE(X[4], data, 16); 64 GET_UINT32_LE(X[5], data, 20); 65 GET_UINT32_LE(X[6], data, 24); 66 GET_UINT32_LE(X[7], data, 28); 67 GET_UINT32_LE(X[8], data, 32); 68 GET_UINT32_LE(X[9], data, 36); 69 GET_UINT32_LE(X[10], data, 40); 70 GET_UINT32_LE(X[11], data, 44); 71 GET_UINT32_LE(X[12], data, 48); 72 GET_UINT32_LE(X[13], data, 52); 73 GET_UINT32_LE(X[14], data, 56); 74 GET_UINT32_LE(X[15], data, 60); 75 76 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 77 78 #define P(a,b,c,d,k,s,t) 79 { 80 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; 81 } 82 83 A = ctx->state[0]; 84 B = ctx->state[1]; 85 C = ctx->state[2]; 86 D = ctx->state[3]; 87 88 #define F(x,y,z) (z ^ (x & (y ^ z))) 89 90 P(A, B, C, D, 0, 7, 0xD76AA478); 91 P(D, A, B, C, 1, 12, 0xE8C7B756); 92 P(C, D, A, B, 2, 17, 0x242070DB); 93 P(B, C, D, A, 3, 22, 0xC1BDCEEE); 94 P(A, B, C, D, 4, 7, 0xF57C0FAF); 95 P(D, A, B, C, 5, 12, 0x4787C62A); 96 P(C, D, A, B, 6, 17, 0xA8304613); 97 P(B, C, D, A, 7, 22, 0xFD469501); 98 P(A, B, C, D, 8, 7, 0x698098D8); 99 P(D, A, B, C, 9, 12, 0x8B44F7AF); 100 P(C, D, A, B, 10, 17, 0xFFFF5BB1); 101 P(B, C, D, A, 11, 22, 0x895CD7BE); 102 P(A, B, C, D, 12, 7, 0x6B901122); 103 P(D, A, B, C, 13, 12, 0xFD987193); 104 P(C, D, A, B, 14, 17, 0xA679438E); 105 P(B, C, D, A, 15, 22, 0x49B40821); 106 107 #undef F 108 109 #define F(x,y,z) (y ^ (z & (x ^ y))) 110 111 P(A, B, C, D, 1, 5, 0xF61E2562); 112 P(D, A, B, C, 6, 9, 0xC040B340); 113 P(C, D, A, B, 11, 14, 0x265E5A51); 114 P(B, C, D, A, 0, 20, 0xE9B6C7AA); 115 P(A, B, C, D, 5, 5, 0xD62F105D); 116 P(D, A, B, C, 10, 9, 0x02441453); 117 P(C, D, A, B, 15, 14, 0xD8A1E681); 118 P(B, C, D, A, 4, 20, 0xE7D3FBC8); 119 P(A, B, C, D, 9, 5, 0x21E1CDE6); 120 P(D, A, B, C, 14, 9, 0xC33707D6); 121 P(C, D, A, B, 3, 14, 0xF4D50D87); 122 P(B, C, D, A, 8, 20, 0x455A14ED); 123 P(A, B, C, D, 13, 5, 0xA9E3E905); 124 P(D, A, B, C, 2, 9, 0xFCEFA3F8); 125 P(C, D, A, B, 7, 14, 0x676F02D9); 126 P(B, C, D, A, 12, 20, 0x8D2A4C8A); 127 128 #undef F 129 130 #define F(x,y,z) (x ^ y ^ z) 131 132 P(A, B, C, D, 5, 4, 0xFFFA3942); 133 P(D, A, B, C, 8, 11, 0x8771F681); 134 P(C, D, A, B, 11, 16, 0x6D9D6122); 135 P(B, C, D, A, 14, 23, 0xFDE5380C); 136 P(A, B, C, D, 1, 4, 0xA4BEEA44); 137 P(D, A, B, C, 4, 11, 0x4BDECFA9); 138 P(C, D, A, B, 7, 16, 0xF6BB4B60); 139 P(B, C, D, A, 10, 23, 0xBEBFBC70); 140 P(A, B, C, D, 13, 4, 0x289B7EC6); 141 P(D, A, B, C, 0, 11, 0xEAA127FA); 142 P(C, D, A, B, 3, 16, 0xD4EF3085); 143 P(B, C, D, A, 6, 23, 0x04881D05); 144 P(A, B, C, D, 9, 4, 0xD9D4D039); 145 P(D, A, B, C, 12, 11, 0xE6DB99E5); 146 P(C, D, A, B, 15, 16, 0x1FA27CF8); 147 P(B, C, D, A, 2, 23, 0xC4AC5665); 148 149 #undef F 150 151 #define F(x,y,z) (y ^ (x | ~z)) 152 153 P(A, B, C, D, 0, 6, 0xF4292244); 154 P(D, A, B, C, 7, 10, 0x432AFF97); 155 P(C, D, A, B, 14, 15, 0xAB9423A7); 156 P(B, C, D, A, 5, 21, 0xFC93A039); 157 P(A, B, C, D, 12, 6, 0x655B59C3); 158 P(D, A, B, C, 3, 10, 0x8F0CCC92); 159 P(C, D, A, B, 10, 15, 0xFFEFF47D); 160 P(B, C, D, A, 1, 21, 0x85845DD1); 161 P(A, B, C, D, 8, 6, 0x6FA87E4F); 162 P(D, A, B, C, 15, 10, 0xFE2CE6E0); 163 P(C, D, A, B, 6, 15, 0xA3014314); 164 P(B, C, D, A, 13, 21, 0x4E0811A1); 165 P(A, B, C, D, 4, 6, 0xF7537E82); 166 P(D, A, B, C, 11, 10, 0xBD3AF235); 167 P(C, D, A, B, 2, 15, 0x2AD7D2BB); 168 P(B, C, D, A, 9, 21, 0xEB86D391); 169 170 #undef F 171 172 ctx->state[0] += A; 173 ctx->state[1] += B; 174 ctx->state[2] += C; 175 ctx->state[3] += D; 176 } 177 178 /* 179 * MD5 process buffer 180 */ 181 void md5::md5_update(md5_context *ctx, const unsigned char *input, size_t ilen) 182 { 183 size_t fill; 184 uint32_t left; 185 186 if (ilen == 0) 187 return; 188 189 left = ctx->total[0] & 0x3F; 190 fill = 64 - left; 191 192 ctx->total[0] += (uint32_t)ilen; 193 ctx->total[0] &= 0xFFFFFFFF; 194 195 if (ctx->total[0] < (uint32_t)ilen) 196 ctx->total[1]++; 197 198 if (left && ilen >= fill) 199 { 200 memcpy((void *)(ctx->buffer + left), input, fill); 201 md5_process(ctx, ctx->buffer); 202 input += fill; 203 ilen -= fill; 204 left = 0; 205 } 206 207 while (ilen >= 64) 208 { 209 md5_process(ctx, input); 210 input += 64; 211 ilen -= 64; 212 } 213 214 if (ilen > 0) 215 { 216 memcpy((void *)(ctx->buffer + left), input, ilen); 217 } 218 } 219 220 static const unsigned char md5_padding[64] = 221 { 222 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 226 }; 227 228 /* 229 * MD5 final digest 230 */ 231 void md5::md5_finish(md5_context *ctx, unsigned char output[16]) 232 { 233 uint32_t last, padn; 234 uint32_t high, low; 235 unsigned char msglen[8]; 236 237 high = (ctx->total[0] >> 29) 238 | (ctx->total[1] << 3); 239 low = (ctx->total[0] << 3); 240 241 PUT_UINT32_LE(low, msglen, 0); 242 PUT_UINT32_LE(high, msglen, 4); 243 244 last = ctx->total[0] & 0x3F; 245 padn = (last < 56) ? (56 - last) : (120 - last); 246 247 md5_update(ctx, md5_padding, padn); 248 md5_update(ctx, msglen, 8); 249 250 PUT_UINT32_LE(ctx->state[0], output, 0); 251 PUT_UINT32_LE(ctx->state[1], output, 4); 252 PUT_UINT32_LE(ctx->state[2], output, 8); 253 PUT_UINT32_LE(ctx->state[3], output, 12); 254 } 255 256 /* 257 * output = MD5( input buffer ) 258 */ 259 void md5::string_md5(const unsigned char *input, size_t ilen, unsigned char output[16]) 260 { 261 md5_context ctx; 262 263 md5_init(&ctx); 264 md5_starts(&ctx); 265 md5_update(&ctx, input, ilen); 266 md5_finish(&ctx, output); 267 md5_free(&ctx); 268 } 269 270 /* 271 * output = MD5( file contents ) 272 */ 273 int md5::file_md5(const char *path, unsigned char output[16]) 274 { 275 FILE *f; 276 size_t n; 277 md5_context ctx; 278 unsigned char buf[1024]; 279 280 if ((f = fopen(path, "rb")) == NULL) 281 return -1; 282 283 md5_init(&ctx); 284 md5_starts(&ctx); 285 286 while ((n = fread(buf, 1, sizeof(buf), f)) > 0) 287 md5_update(&ctx, buf, n); 288 289 md5_finish(&ctx, output); 290 md5_free(&ctx); 291 292 if (ferror(f) != 0) 293 { 294 fclose(f); 295 return -1; 296 } 297 298 fclose(f); 299 return(0); 300 }
标签:
原文地址:http://www.cnblogs.com/emyueguang/p/4547402.html