I have made many researches about MD5 of an xls file but my effort seems be in vain I tried to used lirary and recommendation in this link "https://stackoverflow.com/questions/27858288/calculate-md5-for-a-file-in-c-language" but , still give wrong result , can you help me ??
-
`MD5` of an xls file? it doesn't make sense, you should read the file to a buffer, and then use an implementation of `md5` hashing algorithm on the buffer. – Iharob Al Asimi Jan 12 '15 at 17:45
-
2The structural contents of the file are irrelevant - MD5 produces a message digest for any stream of bytes. – maerics Jan 12 '15 at 17:48
-
The question you link to, is using `fp=fopen(file,"r");` to open a file. That would give a wrong result for any binary file, including xls files. – wimh Jan 12 '15 at 17:48
-
@M.A.E The question to which you're referring seems to be deleted ... – TheByeByeMan Jan 19 '15 at 15:51
3 Answers
MD5 of xls file is very same of MD5 of any other kind of file since it operates on bytes. See by example openssl implementation openssl/crypto/md5/md5.c and md5test.c ( code is in git://git.openssl.org/openssl.git ).

- 3,096
- 29
- 36
Well I used to answer the link you gave but then the question was closed. The idea is as follows. First read the file into a buffer. You can do this using following function:
unsigned char * readFile(const char *path)
{
FILE * pFile;
long lSize;
unsigned char * buffer;
size_t result;
pFile = fopen (path , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = malloc (sizeof(char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
// terminate
fclose (pFile);
return buffer;
}
Read the file
unsigned char * data = readFile("c:\\file.xls");
Then you must apply MD5 on this buffer of data. You can use code similar to the one in that question (though I am not sure which library/implementation of md5 author of that question used). e.g.,
char hash[64] = {0};
md5_byte_t digest[16] = {0};
md5_init(&state);
md5_append(&state, (const md5_byte_t *)data, filesize);
md5_finish(&state,digest);
int i=0;
for(i; i<16; i++)
{
snprintf(hash + i*2,sizeof(hash),"%02x",digest[i]);
}
Now hash
should store the hash of the file, encoded in hexadecimal string. ps. Indeed that sample is incorrectly using strlen
with binary file. That is why I suggested the readFile
method above; that function also contains code to get file size - you can use that code to get file size and then pass the file size to md5_append
method.
ps. also don't forget to free
data
when you are done with it.

- 27,046
- 9
- 53
- 90
The problem is that your example uses strlen
to determine the file size. But .xls
format is binary, so strlen will not work properly.
Adapt the function to return the total data read from the file, and it should work.
Edit. Try something like this code:
void *addr;
struct stat s;
int ret, fd;
ret = stat(filename, &s);
if (ret) {
fprintf(stderr, "Error while stat()ing file: %m\n");
return -1;
}
fd = open(filename, O_RDONLY);;
if (fd < 0) {
fprintf(stderr, "Error while opening file: %m\n");
return -1;
}
addr = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
fprintf(stderr, "Error while mapping file: %m\n");
close(fd);
return -1;
}
md5_init(&state);
md5_append(&state,addr, s.st_size);
md5_finish(&state,digest);

- 1,107
- 9
- 14
-
@user300234 yeah, `strCopy` will not work either, but it is the same problem. Anyway, improved my answer. – Jonatan Goebel Jan 12 '15 at 19:00