我有代码,必须将 0x3B9ACA02432543 更改为某个值,以使该代码的结果等于 cksum 结果。
我尝试将其更改为 cksum 默认值 0x04C11DB7 但结果值不同
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s <file>\n", argv[0]);
exit(EXIT_FAILURE);
} else {
FILE *f = NULL;
int c;
f = fopen(argv[1], "rb");
if (f == NULL)
perror("fopen()");
else {
int size = 0;
int crc;
int c;
int i, j;
int crc_table[256];
for (i = 0; i < 256; i++) {
crc = i;
for (j = 0; j < 8; j++)
crc = crc & 1 ? (crc >> 1) ^ 0x3B9ACA02432543 : crc >> 1;
crc_table[i] = crc;
}
crc = 0;
while ((c = fgetc(f)) != EOF) {
++size;
crc = crc_table[(crc ^ c) & 0xFF] ^ (crc >> 8);
}
crc ^= 0xFFFFFFFFUL;
printf("%u\n", crc);
}
}
return 0;
}```
为了使代码与
cksum
实用程序兼容,您需要使用与 cksum
使用的相同算法。 cksum
实用程序通常使用多项式为 0x04C11DB7
的 CRC 算法。以下是您的代码中需要解决的一些问题:
多项式
0x3B9ACA02432543
对于 32 位 CRC 来说太大。多项式应该是 32 位值,通常为 0x04C11DB7
表示 cksum
。
您需要在计算开始时将
crc
初始化为0xFFFFFFFFUL
。
对于典型的 CRC32 计算,表初始化和计算算法似乎不正确。
这是你可以做的:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s <file>\n", argv[0]);
exit(EXIT_FAILURE);
} else {
FILE *f = NULL;
int c;
f = fopen(argv[1], "rb");
if (f == NULL)
perror("fopen()");
else {
unsigned int crc;
unsigned int crc_table[256];
unsigned int poly = 0x04C11DB7; // Polynomial for cksum
unsigned int temp_crc;
// Build CRC table
for (int i = 0; i < 256; i++) {
temp_crc = i << 24;
for (int j = 0; j < 8; j++) {
if (temp_crc & 0x80000000)
temp_crc = (temp_crc << 1) ^ poly;
else
temp_crc <<= 1;
}
crc_table[i] = temp_crc;
}
crc = 0xFFFFFFFF; // Initialize CRC
while ((c = fgetc(f)) != EOF) {
crc = (crc << 8) ^ crc_table[((crc >> 24) ^ c) & 0xFF];
}
crc = ~crc; // Finalize CRC
printf("%u\n", crc);
}
}
return 0;
}