Is CRC32 supplement?

In several places I read that crc32 is additive, and therefore: CRC (A xor B) = CRC (A) xor CRC (B).

The above statement was refuted by the following code that I wrote:

import zlib def crc32(data): return zlib.crc32(data) & 0xffffffff print crc32(chr(ord("A") ^ ord("B"))) print crc32("A") ^ crc32("B") 

Program output:

 1259060791 2567524794 

Can someone provide the correct code to confirm this theory, or tell me where I failed?

+8
python crc32
source share
4 answers

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.

+3
source share

If a, b, and c are the same length, CRC (a) xor CRC (b) xor CRC (c) is equal to CRC (a xor b xor c). Returning to the original statement, this means that CRC (xor b) is equal to CRC (a) xor CRC (b) xor CRC (z), where z is a sequence of zeros of the same length as the other two sequences.

+2
source share

This would mean that each bit position of the CRC result depends only on the equivalent bit position at the input. Consider your example with B == 0.

The relationships you describe are most likely true for some primitive xor or additive checksum algorithms.

+1
source share

The CRC-32 algorithm is based on polynomial division with the addition of additional steps. The pure polynomial residue is additive.

By this I mean: mod (poly1 + poly2, poly3) = mod (mod (poly1, poly3) + mod (poly2, poly3), poly3)

The CRC-32 algorithm is based on this and is not additive. To compute CRC-32 byte array m:

  • XOR first 4 bytes at 0xFFFFFFFF.
  • Consider earlier bytes as higher polynomial degrees and treat low bits as higher polynomial degrees. For example, bytes 0x01 0x04 will be a polynomial x ^ 15 + x ^ 3.
  • Multiply the polynomial by x ^ 32.
  • Take the remainder of this polynomial divided by the polynomial CRC-32, 0x104C11DB7. The remaining polynomial has degree <32.
  • Treat lower degrees as higher order bits. For example, a polynomial x ^ 2 will be a 32-bit integer 0x40000000.
  • XOR result is 0xFFFFFFFF.

The remainder operation of the pure polynomial is in step 4. These are steps No. 1 and No. 6, which make the CRC-32 algorithm non-additive. Therefore, if you cancel the steps # 1 and # 6, you can modify the CRC-32 algorithm to be additive.

(See also: Python CRC-32 Issues )

+1
source share

All Articles