如何使用C语言制作文件的校验和?我不想使用第三方库,只使用默认的C语言,并且速度非常重要(尽管文件大小小于50MB)。
谢谢!
我建议先从简单的开始,如果后面出现问题才考虑引入快速需求。
太多时间被浪费在解决不存在的问题上(参见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
函数实际上可以完成两种任务。如果你传递给它一个没有校验和的数据块,它会返回该数据块的校验和。如果你传递给它一个带有校验和的数据块,它将返回零以表示正确的校验和,或返回非零值以表示错误的校验和。FILE *fp = fopen("yourfile","rb");
unsigned char checksum = 0;
while (!feof(fp) && !ferror(fp)) {
checksum ^= fgetc(fp);
}
fclose(fp)
fgetc()
返回int
而不是char
,因为EOF
是一个负的int
值,不能表示为char
。这段代码将包括从fgetc()
返回的额外的EOF
并在“校验和”中截断为char
值。 - Andrew Henle通常情况下,使用好的多项式的CRC32可能是非加密哈希校验和的最佳选择。点击这里查看一些原因:http://guru.multimedia.cx/crc32-vs-adler32/在右侧单击纠错类别以获取更多与crc相关的文章。