You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用strcmp对比哈希值时else语句返回错误结果(已更新)

解决文件哈希生成与比对的问题

我明白你现在的需求是生成文件的SHA512哈希并存储,同时能比对当前文件哈希和已存储的哈希是否一致。你的代码里确实有几个关键问题需要修正,我来一步步帮你解决:

原代码的主要问题

  • else块未重新计算当前文件哈希:你在else块里直接使用了c[i],但这个变量是第一次生成哈希时的结果,不是当前文件的最新哈希,这会导致比对完全错误。
  • 哈希格式不匹配:你用sprintf(ch1, "%d", c[i])把哈希字节转成了十进制数字字符串,但存储的哈希是十六进制格式的,两者无法正确比对。
  • 读取存储哈希的方式错误:存储的哈希是一行完整的十六进制字符串,不需要循环读取,直接读取整个字符串即可。
  • 代码重复:哈希计算的逻辑在if块里写了一遍,比对时又需要重复写,应该封装成函数避免重复调用。

修正后的完整实现

首先,我们把哈希计算的逻辑封装成一个可复用的函数,这样无论是生成哈希还是比对,都可以调用同一个函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <openssl/sha.h>

// 封装哈希计算函数:计算指定文件的SHA512哈希,存入out_hash缓冲区(需至少SHA512_DIGEST_LENGTH*2 +1字节)
int calculate_sha512(const char *file_path, char *out_hash) {
    FILE *file = fopen(file_path, "rb");
    if (!file) {
        perror("Failed to open file");
        return -1;
    }

    SHA512_CTX mdContext;
    SHA512_Init(&mdContext);

    unsigned char data[1024];
    size_t bytes;
    while ((bytes = fread(data, 1, sizeof(data), file)) != 0) {
        SHA512_Update(&mdContext, data, bytes);
    }

    unsigned char digest[SHA512_DIGEST_LENGTH];
    SHA512_Final(digest, &mdContext);
    fclose(file);

    // 将哈希字节转换为十六进制字符串
    for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) {
        sprintf(out_hash + (i * 2), "%02x", digest[i]);
    }
    out_hash[SHA512_DIGEST_LENGTH * 2] = '\0'; // 确保字符串以null结尾

    return 0;
}

int main() {
    // 假设这些变量是你预先定义的
    const char *hashInBuf = "your_target_file.bin"; // 要计算哈希的目标文件路径
    const char *hashOutBuf = "hash_store.txt";      // 存储哈希的文件路径

    char current_hash[SHA512_DIGEST_LENGTH * 2 + 1];
    if (calculate_sha512(hashInBuf, current_hash) != 0) {
        return 1;
    }

    // 检查哈希存储文件是否存在
    if (access(hashOutBuf, F_OK) == -1) {
        // 哈希文件不存在,生成并存储哈希
        FILE *hash_file = fopen(hashOutBuf, "wt");
        if (!hash_file) {
            perror("Failed to open hash file for writing");
            return 1;
        }
        fprintf(hash_file, "%s", current_hash);
        printf("Generated and stored hash: %s\n", current_hash);
        fclose(hash_file);
    } else {
        // 哈希文件存在,读取存储的哈希并比对
        char stored_hash[SHA512_DIGEST_LENGTH * 2 + 1];
        FILE *hash_file = fopen(hashOutBuf, "r");
        if (!hash_file) {
            perror("Failed to open hash file for reading");
            return 1;
        }
        // 读取完整的哈希字符串
        if (fscanf(hash_file, "%s", stored_hash) != 1) {
            perror("Failed to read stored hash");
            fclose(hash_file);
            return 1;
        }
        fclose(hash_file);

        // 比对两个哈希字符串
        if (strcmp(current_hash, stored_hash) == 0) {
            printf("File is identical - hash matches: %s\n", current_hash);
        } else {
            printf("File has changed!\n");
            printf("Stored hash: %s\n", stored_hash);
            printf("Current hash: %s\n", current_hash);
        }
    }

    return 0;
}

关键改进点说明

  • 封装哈希函数:把SHA512计算和字符串转换的逻辑抽成calculate_sha512函数,避免重复代码,也让主逻辑更清晰。不管是生成还是比对,只需要调用一次这个函数就能得到当前文件的哈希,解决了重复调用的问题。
  • 统一哈希格式:生成和读取的哈希都是十六进制字符串,确保比对时格式完全一致。
  • 正确的比对流程:先计算当前文件的最新哈希,再读取存储的哈希,然后用strcmp直接比较整个字符串,简单可靠。
  • 错误处理:增加了文件操作的错误检查,避免程序在文件打不开时出现未定义行为。

内容的提问来源于stack exchange,提问作者Joseph Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:13:03