最佳答案是正确的,但没有提及:哈希值对于使用的每个缓冲区大小都会有所不同。该值将在散列之间保持一致,因此相同的缓冲区大小每次都会产生相同的散列,但是如果稍后将此散列与相同数据的散列进行比较,则每次调用必须使用相同的缓冲区大小。
另外,如果你想确保你的摘要代码正常运行,并上网与在线哈希网站比较你的哈希,看起来他们使用的缓冲区长度为 1。这也带来了一个有趣的想法:完全可以接受使用 1 的缓冲区长度来散列一个大文件,它只需要更长的时间(duh)。
所以我的经验法则是,如果它仅供内部使用,那么我可以为大文件相应地设置缓冲区长度,但如果它必须与其他系统很好地配合,则将缓冲区长度设置为 1 并处理时间后果.
int hashTargetFile(FILE* fp, unsigned char** md_value, int *md_len) {
#define FILE_BUFFER_LENGTH 1
EVP_MD_CTX *mdctx;
const EVP_MD *md;
int diglen; //digest length
int arrlen = sizeof(char)*EVP_MAX_MD_SIZE + 1;
int arrlen2 = sizeof(char)*FILE_BUFFER_LENGTH + 1;
unsigned char *digest_value = (char*)malloc(arrlen);
char *data = (char*)malloc(arrlen2);
size_t bytes; //# of bytes read from file
mdctx = EVP_MD_CTX_new();
md = EVP_sha512();
if (!mdctx) {
fprintf(stderr, "Error while creating digest context.\n");
return 0;
}
if (!EVP_DigestInit_ex(mdctx, md, NULL)) {
fprintf(stderr, "Error while initializing digest context.\n");
return 0;
}
while (bytes = fread(data, 1, FILE_BUFFER_LENGTH, fp) != 0) {
if (!EVP_DigestUpdate(mdctx, data, bytes)) {
fprintf(stderr, "Error while digesting file.\n");
return 0;
}
}
if (!EVP_DigestFinal_ex(mdctx, digest_value, &diglen)) {
fprintf(stderr, "Error while finalizing digest.\n");
return 0;
}
*md_value = digest_value;
*md_len = diglen;
EVP_MD_CTX_free(mdctx);
return 1;
}