顶部答案是正确的,但没有提到一些事情:哈希值的价值将因使用的每个缓冲区大小而异。该值将在哈希之间保持一致,因此每次使用相同的缓冲区大小将产生相同的哈希值,但是如果将此哈希与稍后对相同数据的哈希进行比较,则必须为每个调用使用相同的缓冲区大小。
此外,如果要确保您的摘要代码正常运行,并在线上使用哈希网站比较您的哈希,似乎它们使用长度为1的缓冲区。这也带来了一个有趣的想法:使用长度为1的缓冲区对大文件进行哈希处理是完全可以接受的,只是需要更长时间(当然)。
因此,我的经验法则是,如果仅供内部使用,则可以相应地设置缓冲区长度以适应大文件,但是如果必须与其他系统兼容,则将缓冲区长度设置为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;
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;
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;
}