CRC 在数学意义上是加法的,因为 CRC 哈希只是所有数据(被视为大整数)的无进位除以多项式常数的余数。使用您的示例,它类似于这种事情:
7 模 5 = 2
6 模 5 = 1
(7 模 5) + (6 模 5) = 3
(7 + 6) 模 5 = 3
在那个类比中,“5”是我们的 CRC 多项式。
这是一个可以使用的示例(基于 gcc):
#include <stdio.h>
#include <x86intrin.h>
int main(void)
{
unsigned int crc_a = __builtin_ia32_crc32si( 0, 5);
printf( "crc(5) = %08X\n", crc_a );
unsigned int crc_b = __builtin_ia32_crc32si( 0, 7);
printf( "crc(7) = %08X\n", crc_b );
unsigned int crc_xor = crc_a ^ crc_b;
printf( "crc(5) XOR crc(7) = %08X\n", crc_xor );
unsigned int crc_xor2 = __builtin_ia32_crc32si( 0, 5 ^ 7);
printf( "crc(5 XOR 7) = %08X\n", crc_xor2 );
return 0;
}
输出如预期:
plxc15034> gcc -mcrc32 -Wall -O3 crctest.c
plxc15034> ./a.out
crc(5) = A6679B4B
crc(7) = 1900B8CA
crc(5) XOR crc(7) = BF672381
crc(5 XOR 7) = BF672381
因为此代码使用 x86 CRC32 指令,它只能在 Intel i7 或更新版本上运行。内在函数将运行的 CRC 哈希作为第一个参数,将要累积的新数据作为第二个参数。返回值是新运行的 CRC。
上述代码中初始运行的 CRC 值 0 至关重要。使用任何其他初始值,CRC 在实际意义上不是“加法”,因为您已经有效地丢弃了有关您要划分的整数的信息。这正是您的示例中正在发生的事情。CRC 函数从不将初始运行的 CRC 值初始化为零,但通常是 -1。原因是 0 的初始 CRC 允许数据中任意数量的前导 0 简单地通过而不改变运行的 CRC 值,该值保持为 0。因此,将 CRC 初始化为 0 在数学上是合理的,但出于计算的实际目的哈希,这是你想要的最后一件事。