In the CRC-16 calculation what is the difference (if any) between polynomial (x16 + x15 + x2 + x0)
and (x16 + x15 + x2 + 1)
?
Are the same (any number raised to zero is equal to one)?
Can someone explain me how get the hex number from this notation?
I don't understand because these polynomial seems to be 17 bits long:
0x18005
or 0b11000000000000101
No, there is no difference.
The correct way to write those is with superscripts, representing "to the power of":
x16 + x15 + x2 + x0
and:
x16 + x15 + x2 + 1
As you noted, anything raised to the zero power is one.
A 16-bit CRC uses a polynomial of degree 16. That means there must be an x16 term. You have the correct hexadecimal notation 0x18005
. However in writing code to implement the CRC, you can do it with 16-bit operations and don't need the high 1
. In the code you will see an exclusive-or with 0x8005
. The high 1
is in fact being taken into account in the conditional that decides whether or not to exclusive-or with 0x8005
.
Here is an example in C:
uint16_t crc16umts(uint16_t crc, uint8_t const *data, size_t len) {
for (size_t i = 0; i < len; i++) {
crc ^= (uint16_t)data[i] << 8;
for (unsigned k = 0; k < 8; k++)
crc = crc & 0x8000 ? (crc << 1) ^ 0x8005 : crc << 1;
}
return crc;
}
The crc & 0x8000
is checking the high bit of crc
which is about to be shifted up and out, before it is shifted out, to decide whether or not to exclusive-or with 0x8005
after the shift. That is the same as doing it in a 32-bit register instead, doing the shift first, and if the 16th bit (0x10000
) is one, then exclusive-oring with 0x18005
to effect the polynomial remainder operation. So that innermost line of code could have been, with a uint32_t crc
:
crc <<= 1;
if (crc & 0x10000)
crc ^= 0x18005;