CRC is additive in the mathematical sense, because the CRC hash is just the remainder of the useless division of all data (considered as a giant integer) divided by the polynomial constant. Using your example, it looks like things like this:
7 mod 5 = 2
6 mod 5 = 1
(7 mod 5) + (6 mod 5) = 3
(7 + 6) mod 5 = 3
In this analogy, β5β is our CRC polynomial.
Here is an example game with (based on 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; }
The output will be as expected:
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
Since this code uses the x86 CRC32 instruction, it will only work on Intel i7 or later. The internal function takes the current CRC hash as the first parameter, and new data is accumulated as the second parameter. The return value is the new managed CRC.
The CRC 0 start value in the above code is critical. Using any other initial value, then the CRC is not βadditiveβ in the practical sense, because you are effectively throwing out information about the whole into which you divide. And this is exactly what happens in your example. CRC functions never initialize this initial CRC value to zero, but usually -1. The reason is that the original CRC from 0 allows you to simply skip any number of leading 0s in the data without changing the current CRC value, which remains equal to 0. Thus, initializing the CRC to 0 is mathematically justified, but for practical purposes, hash calculation is the last, what you need.