C文件校验和

C文件校验和,c,checksum,C,Checksum,如何使用C对文件进行校验和?我不想使用任何第三方,只是默认的c语言,而且速度是非常重要的(它小于50mb的文件,但无论如何) 谢谢我建议使用BSD实现。比如说, 确定要使用的算法(例如CRC32) 在维基百科或其他来源上查找算法 编写代码来实现该算法 如果/当代码没有正确实现算法时,在此处发布问题 利润 我建议从简单的开始,然后只担心引入fast需求,如果这是一个问题的话 在解决不存在的问题上浪费了太多的时间(请参见YAGNI) 简单地说,我的意思是简单地从零开始一个校验和字符(这里的所有字符都

如何使用C对文件进行校验和?我不想使用任何第三方,只是默认的c语言,而且速度是非常重要的(它小于50mb的文件,但无论如何)


谢谢

我建议使用BSD实现。比如说,

  • 确定要使用的算法(例如CRC32)
  • 在维基百科或其他来源上查找算法
  • 编写代码来实现该算法
  • 如果/当代码没有正确实现算法时,在此处发布问题
  • 利润

  • 我建议从简单的开始,然后只担心引入fast需求,如果这是一个问题的话

    在解决不存在的问题上浪费了太多的时间(请参见
    YAGNI

    简单地说,我的意思是简单地从零开始一个校验和字符(这里的所有字符都是无符号的),读入每个字符并从校验和字符中减去它,直到到达文件的结尾,假设您的实现是智能包装的

    类似于以下程序中的内容:

    #include <stdio.h>
    
    unsigned char checksum (unsigned char *ptr, size_t sz) {
        unsigned char chk = 0;
        while (sz-- != 0)
            chk -= *ptr++;
        return chk;
    }
    
    int main(int argc, char* argv[])
    {
        unsigned char x[] = "Hello_";
        unsigned char y = checksum (x, 5);
        printf ("Checksum is 0x%02x\n", y);
        x[5] = y;
        y = checksum (x, 6);
        printf ("Checksum test is 0x%02x\n", y);
        return 0;
    }
    
    这个
    校验和
    函数实际上完成了这两项工作。如果您向它传递一个数据块,但末尾没有校验和,它将为您提供校验和。如果您传递一个末尾带有校验和的块,那么好的校验和将为零,如果校验和不好,则为非零

    这是最简单的方法,可以检测大多数随机错误。它不会检测像两个交换字符这样的边缘情况,因此,如果您需要更准确的信息,请使用或之类的方法

    这两个维基百科页面都有示例C代码,您可以按原样使用,也可以分析和重新编码,以避免IP问题。

    简单快速

    FILE *fp = fopen("yourfile","rb");
    unsigned char checksum = 0;
    while (!feof(fp) && !ferror(fp)) {
       checksum ^= fgetc(fp);
    }
    
    fclose(fp)
    

    通常,具有良好多项式的CRC32可能是非加密哈希校验和的最佳选择。请参见此处,原因如下:单击右侧的纠错类别可获得更多与crc相关的帖子。

    是否有您感兴趣的特定校验和/哈希算法?如果有,请选择“快速简单算法”。如果测试正确,只需将布尔值设为“真”。任何校验和都比磁盘I/O快得多,所以这并不重要。你需要决定你想要什么。如果你想要一个加密散列,这与CRC32或杂音有点不同。-1有更好的散列函数仍然很简单@凯泽,这与简单无关。您提供的链接中的那些函数是散列函数,它们的用途与校验和完全不同-它们的目的是最大化密钥分配的存储桶之间的平衡,而不是简单地获取用于检查的文件“值”的指示(它们可以用于此目的,但在这种情况下没有任何好处)。此外,它们都执行比简单加法更复杂的操作,并且引用一个问题,“速度非常重要”。简单地添加所有字符是最简单的校验和,当然,但它不能防止任何交换,例如
    “Holle_”
    @Kaizer,我不确定什么是“交换”你说的是这里,但我假设你是指文件中某个地方的交换字符。但任何校验和(或散列)都容易受到无法检测的输入值错误的影响。这是它们的本质,因为它们涉及信息丢失。如果使输出值更依赖于位置(例如使用djb2),则可以提高捕获其中一些问题的可能性,但这会引入额外的计算,从而减慢过程。正是对速度的强调让我专注于简单的解决方案。然而,我不是来为我的案件辩护的,你已经打了电话,我所能做的就是解释为什么我认为你错了:-)我真的不想用更多的解释来堵塞评论系统,所以我就把它留在那里。
    FILE *fp = fopen("yourfile","rb");
    unsigned char checksum = 0;
    while (!feof(fp) && !ferror(fp)) {
       checksum ^= fgetc(fp);
    }
    
    fclose(fp)