从文件中截取字段并转换为MD5值

首先需要实现MD5,网上发现一个较好的实现:

1、md5.h

 1 #ifndef _MD5_H_
 2 #define _MD5_H_
 3 /*
 4  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
 5  * MD5 Message-Digest Algorithm (RFC 1321).
 6  *
 7  * Homepage:
 8  * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
 9  *
10  * Author:
11  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
12  *
13  * This software was written by Alexander Peslyak in 2001.  No copyright is
14  * claimed, and the software is hereby placed in the public domain.
15  * In case this attempt to disclaim copyright and place the software in the
16  * public domain is deemed null and void, then the software is
17  * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
18  * general public under the following terms:
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted.
22  *
23  * There's ABSOLUTELY NO WARRANTY, express or implied.
24  *
25  * See md5.c for more information.
26  */
27 
28 
29 /* Any 32-bit or wider unsigned integer data type will do */
30 typedef unsigned int MD5_u32plus;
31 
32 typedef struct {
33     MD5_u32plus lo, hi;
34     MD5_u32plus a, b, c, d;
35     unsigned char buffer[64];
36     MD5_u32plus block[16];
37 } MD5_CTX;
38 
39 extern void MD5_Init(MD5_CTX *ctx);
40 extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
41 extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
42 
43 
44 #endif // _MD5_H_

2、md5.c

  1 /*
  2  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
  3  * MD5 Message-Digest Algorithm (RFC 1321).
  4  *
  5  * Homepage:
  6  * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
  7  *
  8  * Author:
  9  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
 10  *
 11  * This software was written by Alexander Peslyak in 2001.  No copyright is
 12  * claimed, and the software is hereby placed in the public domain.
 13  * In case this attempt to disclaim copyright and place the software in the
 14  * public domain is deemed null and void, then the software is
 15  * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
 16  * general public under the following terms:
 17  *
 18  * Redistribution and use in source and binary forms, with or without
 19  * modification, are permitted.
 20  *
 21  * There's ABSOLUTELY NO WARRANTY, express or implied.
 22  *
 23  * (This is a heavily cut-down "BSD license".)
 24  *
 25  * This differs from Colin Plumb's older public domain implementation in that
 26  * no exactly 32-bit integer data type is required (any 32-bit or wider
 27  * unsigned integer data type will do), there's no compile-time endianness
 28  * configuration, and the function prototypes match OpenSSL's.  No code from
 29  * Colin Plumb's implementation has been reused; this comment merely compares
 30  * the properties of the two independent implementations.
 31  *
 32  * The primary goals of this implementation are portability and ease of use.
 33  * It is meant to be fast, but not as fast as possible.  Some known
 34  * optimizations are not included to reduce source code size and avoid
 35  * compile-time configuration.
 36  */
 37 
 38 #include <string.h>
 39 
 40 #include "md5.h"
 41 
 42 /*
 43  * The basic MD5 functions.
 44  *
 45  * F and G are optimized compared to their RFC 1321 definitions for
 46  * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
 47  * implementation.
 48  */
 49 #define F(x, y, z)            ((z) ^ ((x) & ((y) ^ (z))))
 50 #define G(x, y, z)            ((y) ^ ((z) & ((x) ^ (y))))
 51 #define H(x, y, z)            (((x) ^ (y)) ^ (z))
 52 #define H2(x, y, z)            ((x) ^ ((y) ^ (z)))
 53 #define I(x, y, z)            ((y) ^ ((x) | ~(z)))
 54 
 55 /*
 56  * The MD5 transformation for all four rounds.
 57  */
 58 #define STEP(f, a, b, c, d, x, t, s) \
 59     (a) += f((b), (c), (d)) + (x) + (t); \
 60     (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
 61     (a) += (b);
 62 
 63 /*
 64  * SET reads 4 input bytes in little-endian byte order and stores them
 65  * in a properly aligned word in host byte order.
 66  *
 67  * The check for little-endian architectures that tolerate unaligned
 68  * memory accesses is just an optimization.  Nothing will break if it
 69  * doesn't work.
 70  */
 71 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
 72 #define SET(n) \
 73     (*(MD5_u32plus *)&ptr[(n) * 4])
 74 #define GET(n) \
 75     SET(n)
 76 #else
 77 #define SET(n) \
 78     (ctx->block[(n)] = \
 79     (MD5_u32plus)ptr[(n) * 4] | \
 80     ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
 81     ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
 82     ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
 83 #define GET(n) \
 84     (ctx->block[(n)])
 85 #endif
 86 
 87 /*
 88  * This processes one or more 64-byte data blocks, but does NOT update
 89  * the bit counters.  There are no alignment requirements.
 90  */
 91 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
 92 {
 93     const unsigned char *ptr;
 94     MD5_u32plus a, b, c, d;
 95     MD5_u32plus saved_a, saved_b, saved_c, saved_d;
 96 
 97     ptr = (const unsigned char *)data;
 98 
 99     a = ctx->a;
100     b = ctx->b;
101     c = ctx->c;
102     d = ctx->d;
103 
104     do {
105         saved_a = a;
106         saved_b = b;
107         saved_c = c;
108         saved_d = d;
109 
110 /* Round 1 */
111         STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
112         STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
113         STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
114         STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
115         STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
116         STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
117         STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
118         STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
119         STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
120         STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
121         STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
122         STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
123         STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
124         STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
125         STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
126         STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
127 
128 /* Round 2 */
129         STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
130         STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
131         STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
132         STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
133         STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
134         STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
135         STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
136         STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
137         STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
138         STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
139         STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
140         STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
141         STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
142         STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
143         STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
144         STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
145 
146 /* Round 3 */
147         STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
148         STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
149         STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
150         STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
151         STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
152         STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
153         STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
154         STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
155         STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
156         STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
157         STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
158         STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
159         STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
160         STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
161         STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
162         STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
163 
164 /* Round 4 */
165         STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
166         STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
167         STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
168         STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
169         STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
170         STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
171         STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
172         STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
173         STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
174         STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
175         STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
176         STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
177         STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
178         STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
179         STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
180         STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
181 
182         a += saved_a;
183         b += saved_b;
184         c += saved_c;
185         d += saved_d;
186 
187         ptr += 64;
188     } while (size -= 64);
189 
190     ctx->a = a;
191     ctx->b = b;
192     ctx->c = c;
193     ctx->d = d;
194 
195     return ptr;
196 }
197 
198 void MD5_Init(MD5_CTX *ctx)
199 {
200     ctx->a = 0x67452301;
201     ctx->b = 0xefcdab89;
202     ctx->c = 0x98badcfe;
203     ctx->d = 0x10325476;
204 
205     ctx->lo = 0;
206     ctx->hi = 0;
207 }
208 
209 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
210 {
211     MD5_u32plus saved_lo;
212     unsigned long used, available;
213 
214     saved_lo = ctx->lo;
215     if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
216         ctx->hi++;
217     ctx->hi += size >> 29;
218 
219     used = saved_lo & 0x3f;
220 
221     if (used) {
222         available = 64 - used;
223 
224         if (size < available) {
225             memcpy(&ctx->buffer[used], data, size);
226             return;
227         }
228 
229         memcpy(&ctx->buffer[used], data, available);
230         data = (const unsigned char *)data + available;
231         size -= available;
232         body(ctx, ctx->buffer, 64);
233     }
234 
235     if (size >= 64) {
236         data = body(ctx, data, size & ~(unsigned long)0x3f);
237         size &= 0x3f;
238     }
239 
240     memcpy(ctx->buffer, data, size);
241 }
242 
243 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
244 {
245     unsigned long used, available;
246 
247     used = ctx->lo & 0x3f;
248 
249     ctx->buffer[used++] = 0x80;
250 
251     available = 64 - used;
252 
253     if (available < 8) {
254         memset(&ctx->buffer[used], 0, available);
255         body(ctx, ctx->buffer, 64);
256         used = 0;
257         available = 64;
258     }
259 
260     memset(&ctx->buffer[used], 0, available - 8);
261 
262     ctx->lo <<= 3;
263     ctx->buffer[56] = ctx->lo;
264     ctx->buffer[57] = ctx->lo >> 8;
265     ctx->buffer[58] = ctx->lo >> 16;
266     ctx->buffer[59] = ctx->lo >> 24;
267     ctx->buffer[60] = ctx->hi;
268     ctx->buffer[61] = ctx->hi >> 8;
269     ctx->buffer[62] = ctx->hi >> 16;
270     ctx->buffer[63] = ctx->hi >> 24;
271 
272     body(ctx, ctx->buffer, 64);
273 
274     result[0] = ctx->a;
275     result[1] = ctx->a >> 8;
276     result[2] = ctx->a >> 16;
277     result[3] = ctx->a >> 24;
278     result[4] = ctx->b;
279     result[5] = ctx->b >> 8;
280     result[6] = ctx->b >> 16;
281     result[7] = ctx->b >> 24;
282     result[8] = ctx->c;
283     result[9] = ctx->c >> 8;
284     result[10] = ctx->c >> 16;
285     result[11] = ctx->c >> 24;
286     result[12] = ctx->d;
287     result[13] = ctx->d >> 8;
288     result[14] = ctx->d >> 16;
289     result[15] = ctx->d >> 24;
290 
291     memset(ctx, 0, sizeof(*ctx));
292 }

3、简单测试

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include "md5.h"
 5 
 6 // enter start position and end position
 7 unsigned char* getMD5InRange(const char* filename, long startpos, long endpos)
 8 {
 9     FILE* file = fopen(filename, "r");
10     fseek(file, startpos, SEEK_SET);     // redirect the file pointer to start position
11     char *buf = (char *)malloc(endpos-startpos+1);
12     fread(buf, sizeof(char), endpos-startpos+1, file);       // read the data to buffer
13 
14     printf("buf: %s\n", buf);
15     unsigned char *decrypt = (unsigned char *)malloc(sizeof(unsigned char*)*16);
16     MD5_CTX md5;        
17     MD5_Init(&md5);        // three steps to get md5
18     MD5_Update(&md5, buf, strlen(buf));
19     MD5_Final(decrypt, &md5);
20     fclose(file);
21     return decrypt;
22 }
23 
24 
25 int main(int argc, char* argv[])
26 {
27     int i, st, ed;
28     unsigned char *decrypt2;
29     
30     while(~scanf("%d%d", &st, &ed))
31     {
32         decrypt2 = getMD5InRange("aaa.txt", st, ed);
33         for(i = 0; i < 16; i++)
34             printf("%02x", decrypt2[i]);
35         printf("\n");
36     }
37     return 0;
38 }

4、文本文件aaa.txt

shanghaisndacompanygrandcloudwww.grandcloud.com

5、Makefile

test: test.o md5.o
    cc -o test test.o md5.o
test.o : test.c md5.h
    cc -c test.c md5.c

6、运行结果(centos6.6,请在unix环境下编译运行)

 

posted @ 2015-04-30 15:01  Sign_  阅读(1186)  评论(0编辑  收藏  举报