【问题标题】:C file checksumC 文件校验和
【发布时间】:2010-08-12 00:57:41
【问题描述】:

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

谢谢

【问题讨论】:

  • 是否有您感兴趣的特定校验和/哈希算法?
  • “快速简单的”,如果有的话..如果测试没问题,只想把“真”变成布尔值
  • 任何校验和都比磁盘 I/O 快得多,所以这并不重要。你需要在这里决定你想要什么。如果你想要一个加密哈希,这与 CRC32 或 Murmur 有点不同。

标签: c checksum


【解决方案1】:

我建议从 simple 开始,然后只担心引入 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;
}

哪个输出:

Checksum is 0x0c
Checksum test is 0x00

checksum 函数实际上完成了两项工作。如果你向它传递一个最后没有校验和的数据块,它会给你校验和。如果你把一个带有校验和的块传递给它,它会给你一个好的校验和,如果校验和不好,它会给你零。

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

这两个 Wikipedia 页面都有示例 C 代码,您可以按原样使用,也可以分析和重新编码以避免 IP 问题(如果您担心的话)。

【讨论】:

  • -1 有更好的散列函数仍然很简单。 cse.yorku.ca/~oz/hash.html
  • @Kaizer,它与简单无关。您提供的链接中的那些函数是 hash 函数,它们的目的与校验和完全不同 - 它们的目的是最大化存储桶之间的平衡以进行密钥分配,而不仅仅是获取文件“值”的指示用于检查(它们可以使用,但在这种情况下它们没有任何好处)。此外,它们都执行比简单加法更复杂的操作,并且引用这个问题,“速度非常重要”。
  • 简单地添加所有字符是最简单的校验和,当然,但它不能防止像"Holle_"这样的任何交换。
  • @Kaizer,我不确定你在说什么“交换”,但我假设你的意思是文件中某处的交换字符。但是 any 校验和(或与此相关的哈希)容易受到无法检测到的输入值错误的影响。这是它们的本质,因为它们涉及信息丢失。如果您使输出值更依赖于位置(例如使用 djb2),则可以提高捕获其中一些问题的可能性,但这会引入额外的计算,从而减慢处理速度。正是对速度的强调让我专注于简单的解决方案。
  • 但是,我不是来为我的案子辩护的,你已经打电话了,我所能做的就是解释为什么我认为你弄错了 :-) 我真的不想用更多的解释阻塞 cmets 系统,所以我把它留在那里。
【解决方案2】:
  1. 确定要使用的算法(CRC32 就是一个例子)
  2. 在 Wikipedia 或其他来源中查找算法
  3. 编写代码来实现该算法
  4. 如果/当代码未正确实现算法时,请在此处发布问题
  5. 利润?

【讨论】:

    【解决方案3】:

    简单快速

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

    【讨论】:

      【解决方案4】:

      通常,具有良好多项式的 CRC32 可能是非加密哈希校验和的最佳选择。由于某些原因,请参见此处:http://guru.multimedia.cx/crc32-vs-adler32/ 点击右侧的纠错类别以获得更多与 crc 相关的帖子。

      【讨论】:

        【解决方案5】:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-03
          • 2011-10-11
          • 2014-03-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-02
          相关资源
          最近更新 更多