Reputation: 3715
Trying to understand this explanation of CRC16 CCITT, I came across to the term "truncated polynomial". Comparing the long-hand calculation for a one-byte message with the corresponding C code, I found out that the macro definition of poly
doesnt match the calculation example from the above. Into the C code the polynomial is 0x1021
while into the calculation example above the polynomial used is bigger, 0x11021
.
They use the term truncated polynomial for this: 0x1021
. What pattern do they use to extend this 0x1021
to this 0x11021
?
Upvotes: 1
Views: 2860
Reputation: 1490
0x11021
represents polynomial p = x^16+x^12+x^5+x^0
from F2[X]. Message (together with initial value and augmentation) is also represented by a polynomial. CRC is basically just message modulo polynomial p
. Therefore CRC never needs more than 2 bytes. Since p = 0 mod p
we can write x^16 = x^12+x^5+x^0 mod p
. So 0x1021
represents x^12+x^5+x^0
.
Now lets see how update_good_crc
works:
void update_good_crc(unsigned short ch)
{
unsigned short i, v, xor_flag;
/*
Align test bit with leftmost bit of the message byte.
*/
v = 0x80;
for (i=0; i<8; i++)
{
if (good_crc & 0x8000)
{
xor_flag= 1;
}
else
{
xor_flag= 0;
}
good_crc = good_crc << 1;
if (ch & v)
{
/*
Append next bit of message to end of CRC if it is not zero.
The zero bit placed there by the shift above need not be
changed if the next bit of the message is zero.
*/
good_crc= good_crc + 1;
}
if (xor_flag)
{
good_crc = good_crc ^ poly;
}
/*
Align test bit with next bit of the message byte.
*/
v = v >> 1;
}
}
This checks whether most significant bit of good_crc is set to zero. In other words, it checks whether coefficient at x^15 is set to 1 or 0.
if (good_crc & 0x8000)
{
xor_flag= 1;
}
good_crc = good_crc << 1;
this multiplies good_crc by x. Thus coefficient at x^15
becomes coefficient at x^16
and good_crc "overflows" its 16 bits (that's why we stored xor_flag).
good_crc = good_crc ^ poly;
if xor_flag
is set then this "subtracts" x^16 = x^12+x^5+x^0 mod p
from good_crc.
Upvotes: 2