md5_ex1.c
1 |
#include <stdio.h> |
---|---|
2 |
#include <stdlib.h> |
3 |
#include <string.h> |
4 |
#include <sys/stat.h> |
5 |
#include <sys/types.h> |
6 |
#include <unistd.h> |
7 |
#include <errno.h> |
8 |
#include <fcntl.h> |
9 |
|
10 |
#if defined(__APPLE__)
|
11 |
# define COMMON_DIGEST_FOR_OPENSSL
|
12 |
# include <CommonCrypto/CommonDigest.h> |
13 |
# define SHA1 CC_SHA1
|
14 |
#else
|
15 |
# include <openssl/md5.h> |
16 |
#endif
|
17 |
#define BUF_SIZE 1048576L |
18 |
|
19 |
char *f2md5(const char *fname) { |
20 |
int n;
|
21 |
MD5_CTX c; |
22 |
unsigned char digest[16]; |
23 |
long buf_size = BUF_SIZE; /*buffer size for the data blocks*/ |
24 |
unsigned int crc; /*used to hold the crc as it is updated*/ |
25 |
long nb, rest, i; /*loop control variables*/ |
26 |
struct stat sb; /*used with fstat()*/ |
27 |
int fd; /*the file descriptor*/ |
28 |
char buf[BUF_SIZE]; /*the data buffer*/ |
29 |
char *out = (char*)malloc(33); |
30 |
|
31 |
if((fd = open(fname, O_RDONLY)) < 0) |
32 |
{ |
33 |
printf("Unable to open file %s: %s\n", fname, strerror(errno));
|
34 |
exit(1);
|
35 |
} |
36 |
if(fstat(fd, &sb) < 0) |
37 |
{ |
38 |
printf("Unable to stat file %s: %s\n", fname, strerror(errno));
|
39 |
exit(1);
|
40 |
} |
41 |
if(!(S_ISREG(sb.st_mode)))
|
42 |
{ |
43 |
printf("Operation permitted only for regular file.\n");
|
44 |
exit(1);
|
45 |
} |
46 |
|
47 |
/*Initialize values used looping through reading in the file.*/
|
48 |
nb = sb.st_size / buf_size; |
49 |
rest = sb.st_size % buf_size; |
50 |
|
51 |
MD5_Init(&c); |
52 |
|
53 |
/*Read in the file in 'buf_size' sized blocks and calculate CRC.*/
|
54 |
for (i = 0; i < nb; i++){ |
55 |
if(read(fd, buf, buf_size) < 0) |
56 |
{ |
57 |
printf("Error reading file: %s\n", strerror(errno));
|
58 |
exit(1);
|
59 |
} |
60 |
MD5_Update(&c, buf, buf_size); |
61 |
} |
62 |
if (rest)
|
63 |
{ |
64 |
if(read(fd, buf, rest) < 0) |
65 |
{ |
66 |
printf("Error reading file: %s\n", strerror(errno));
|
67 |
exit(1);
|
68 |
} |
69 |
MD5_Update(&c, buf, rest); |
70 |
} |
71 |
|
72 |
|
73 |
|
74 |
MD5_Final(digest, &c); |
75 |
for (n = 0; n < 16; ++n) { |
76 |
snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]); |
77 |
} |
78 |
|
79 |
return out;
|
80 |
} |
81 |
|
82 |
|
83 |
int main(int argc, char **argv) { |
84 |
char *output = f2md5(argv[1]); |
85 |
printf("%s\n", output);
|
86 |
free(output); |
87 |
return 0; |
88 |
} |