我正在尝试使用 OpenSSL 递归计算目录中所有文件的 SHA256 总和。
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#define _MAX_LINE_ 256
int sha256_file (char* path, char output[65]){
FILE* file = fopen(path, "rb");
unsigned char hash[SHA256_DIGEST_LENGTH];
const int bufSize = 32768;
char* buffer = malloc(bufSize);
int bytesRead = 0;
SHA256_CTX sha256;
if(!file)
return -1;
if(!buffer)
return -1;
SHA256_Init(&sha256);
while((bytesRead = fread(buffer, 1, bufSize, file))){
SHA256_Update(&sha256, buffer, bytesRead);
}
SHA256_Final(hash, &sha256);
sha256_hash_string(hash, output);
fclose(file);
free(buffer);
return 0;
}
void sha256_hash_string (unsigned char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65]){
int i = 0;
for(i = 0; i < SHA256_DIGEST_LENGTH; i++){
sprintf(outputBuffer + (i * 2), "%02x", (unsigned char)hash[i]);
}
outputBuffer[64] = 0;
}
void traverse_dirs(char* base_path){
char path[_MAX_LINE_];
struct dirent* dp;
DIR* dir = opendir(base_path);
unsigned char file_sha[65];
char* md5_command;
if(!dir)
return;
while((dp = readdir(dir)) != NULL){
if(strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0){
// calculate the sha256 sum of the file
sha256_file(dp->d_name, file_sha);
// print the name of the file followed by the sha256 sum
printf("%s -> %s\n", dp->d_name, file_sha);
strcpy(path, base_path);
strcat(path, "/");
strcat(path, dp->d_name);
traverse_dirs(path);
}
}
closedir(dir);
}
int main(int argc, char* argv[]){
if(argc < 2){
printf("Usage: <executable> <dirname>\n");
exit(-1);
}
traverse_dirs(argv[1]);
return 0;
}
正如我手动测试的那样,
sha256_file()
函数为每个文件生成正确的 sha256sum。
traverse_dirs()
功能也可以正常工作,因为它可以正确打印所提供目录的内容。
问题是他们不能一起工作。我发现文件在
sha256_file()
函数中无法正确打开(fopen 返回 NULL),但我不明白为什么。如果我在每个文件上手动使用它,它就可以正常工作。
有什么想法吗?
此
sha256_file(dp->d_name, file_sha)
不起作用,因为您不在包含该名称的目录中。您需要使用您在 path[]
中构建的路径。
如果
sha256_file(path)
是常规文件,则应仅调用 path
;如果 traverse_dirs(path)
是目录,则应仅调用 path
。您可以使用 d_type
检查那些。请参阅 dirent 的手册页。