CRC ハッシュは、すべてのデータ (巨大な整数として扱われる) を多項式定数で除算したキャリーレス除算の剰余値であるため、CRC は数学的な意味で加算されます。あなたの例を使用すると、次のようなものに似ています。
7 mod 5 = 2
6 mod 5 = 1
(7 mod 5) + (6 mod 5) = 3
(7 + 6) mod 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 ハッシュを最初のパラメーターとして受け取り、蓄積する新しいデータを 2 番目のパラメーターとして受け取ります。戻り値は、新しい実行中の CRC です。
上記のコードの最初の実行中の CRC 値 0 は重要です。他の初期値を使用すると、分割する整数に関する情報を効果的に破棄するため、CRC は実用的な意味で「加法的」ではありません。そして、これはまさにあなたの例で起こっていることです。CRC 関数は、実行中の CRC の初期値をゼロに初期化することはありませんが、通常は -1 に初期化します。その理由は、初期 CRC が 0 の場合、データ内の任意の数の先頭の 0 が、実行中の CRC 値を変更せずに単純にフォールスルーできるためです。CRC 値は 0 のままです。したがって、CRC を 0 に初期化することは数学的に適切ですが、計算の実用的な目的のためです。ハッシュ、それはあなたが望む最後のものです。