计算 md5

代码从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
View Code
  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 }
View Code
原文地址:https://www.cnblogs.com/emyueguang/p/4547402.html