That should be detect all single burst errors up to 16 bits.
0x11021 is the product of 2 "prime" polynomials, 0xf01f and 0x3. The 0x3 factor is why all odd bit errors are detected (it is a parity factor).
Since all odd bit errors are detected, then this statement becomes detecting all 2 bit errors up to a data size size 32751 bits or a message size of 32767 bits, which includes the 16 bit CRC which is appended to the data bits. For a brute force approach, using a bit string of all zero bits except the first bit which is a one bit, then calculate the CRC over this string until the CRC only has a single one bit as the most significant bit. This can be emulated by starting with a CRC of 0x8000 and cycling it until it cycles back to 0x8000 again, which will take 32767 cycles. So if bit[0] and bit[32768] are == 1 (all other bits == 0), then the calculated CRC will be zero, a failure to detect the 2 error bits.
What kind of errors does CRC cannot detect?
Multiple burst errors where the total distance of the bursts spans more than 16 bits, essentially a single burst error more than 16 bits long.
Some patterns of 4 or more randomly distributed bit errors in a 64 bit message (48 bits data, 16 bits CRC) will fail to be detected. As seen in the table below, the probably of not detecting an error is fairly low. As the number of bit errors increases, the failure rate increases, but it's still low unless you have a lot of bit errors. A random pattern of bits will pass a CRC16 check about 1/65536 of the time, but this would be unusual in a normal message send / receive sequence.
48 bit data, 16 bit crc, => 64 bit message
2^64 - 1 possible error patterns
84 of 635376 possible patterns of 4 error bits fail
2430 of 74974368 possible patterns of 6 error bits fail
133001 of 4426165368 possible patterns of 8 error bits fail
4621021 of 151473214816 possible patterns of 10 error bits fail
100246083 of 3284214703056 possible patterns of 12 error bits fail
Example code for 4 bit case. Set e
to number of error bits to test.
static uint16_t crctbl[65536];
int main()
{
uint32_t I[16]; /* indexes */
uint32_t e = 4; /* # of error bits */
uint32_t i, j;
uint64_t d;
uint32_t crc;
uint64_t ptrn = 0; /* # of patterns */
uint32_t fail = 0; /* # of failures */
for(j = 0; j < 0x10000; j++){ /* generate table */
crc = j;
for (i = 0; i < 16; i++) {
crc <<= 1;
if (crc & 0x10000)
crc ^= 0x11021;
}
crctbl[j] = (uint16_t)crc;
}
for(i = 0; i < e; i++) /* init I */
I[i] = i;
while(1){
d = 0; /* set up pattern */
for(i = 0; i < e; i++)
d |= ((uint64_t)1 << (63-I[i]));
for(j = 0; j < 4; j++){ /* generate crc */
crc = crctbl[ (d >> 48)&0xffff ];
crc = crctbl[crc ^ ((d >> 32)&0xffff)];
crc = crctbl[crc ^ ((d >> 16)&0xffff)];
crc = crctbl[crc ^ ((d >> 0)&0xffff)];
}
ptrn++;
if (crc == 0) /* if failed */
fail++;
i = e - 1; /* advance indexes */
if (++I[i] < 64) /* to next permuation */
continue;
--I[i];
j = 63;
while (I[i--] >= j--) {
if (i == 0) /* show progress */
printf("%u\n", I[0]);
if (i == (uint32_t)(0-1))
goto done0;
}
j = I[++i];
while (i < e)
I[i++] = ++j;
}
done0:
printf("%llu %u\n", ptrn, fail);
return 0;
}