C 中的复制函数未创建匹配的校验和

Copy Function in C not creating matching Checksums

我写了一个简单的复制程序,复制一个文件并生成一个MD5,它运行并正确生成MD5。

但是在验证复制函数生成的文件时,它与源MD5不匹配。我在我的代码中看不到任何原因,有人可以帮忙吗?

#include <stdio.h>
#include <openssl/md5.h>
#include <assert.h>

#define BUFFER_SIZE 512

int secure_copy(char *filepath, char *destpath);

int main(int argc, char * argv[]) {
    secure_copy(argv[1], argv[2]);
    return 0;
}

int secure_copy(char *filepath, char *destpath) {
    FILE *src, *dest;
    src = fopen(filepath, "r");
    assert(src != NULL);

    dest = fopen(destpath, "w");
    assert(dest != 0);

    MD5_CTX c;
    char buf[BUFFER_SIZE];
    ssize_t bytes, out_writer;
    unsigned char out[MD5_DIGEST_LENGTH];
    MD5_Init(&c);

    while((bytes = fread(buf, 1, BUFFER_SIZE, src)) != 0) {
        MD5_Update(&c, buf, bytes);
        out_writer = fwrite(buf, 1, BUFFER_SIZE, dest);
        assert(out_writer != 0);
    }

    MD5_Final(out, &c);
    printf("MD5: ");
    for (int i=0; i < MD5_DIGEST_LENGTH; i++)
    {
        printf("%02x",  out[i]);
    }
    printf("\n");
    fclose(src);
    fclose(dest);
    return 0;
}

输出

$ ./md5speed doc.txt /home/doc.txt
MD5: 4c55e4b9185eece3cc000c4023f8f6fe

当使用 md5sum 验证复制的文件时,我得到了一个完全不同的哈希值。

md5sum doc.txt 
29cb4da30c3e28fdb81463b5f0a76894  doc.txt

虽然文件仍然打开并且内容未损坏。

如评论中所述,将 fwrite 函数更改为使用 bytes 而不是 BUFFER_SIZE,同时将文件操作模式“rb”和“wb”更改为二进制。

关于:

while((bytes = fread(buf, 1, BUFFER_SIZE, src)) != 0)

out_writer = fwrite(buf, 1, BUFFER_SIZE, dest);

在最后一次读取时,读取的数量可能小于 BUFFER_SIZE,因此应始终使用 bytes 变量作为要写入的字节数。

此外,调用 fread() and/or fwrite() 时可能会出现某些错误,此类错误由负值表示(and/or 值小于这些函数的第三个参数) 在返回的变量(字节,外写器)中。代码要健壮,必须检查这些值并处理发生的任何错误,包括 EOF