I came across an allegedly very efficient and elegant CRC implementation and I am trying to really understand all the steps. I understand the CRC-CCITT 0x1021 implementations that iterate over each bit, but I am struggling to get this one. This is the code.
/*
* Original Code by Ashley Roll
*/
uint16_t crc16(uint8_t* data, uint16_t length){
uint8_t x;
uint16_t crc = 0xFFFF;
while (length--){
x = crc >> 8 ^ *data++;
x ^= x>>4;
crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x <<5)) ^ ((uint16_t)x);
}
return crc;
}
Could anyone explain to me a little bit deeper what is going on with the x variable? This is what I was able to grasp until now
x = crc >> 8 ^ *data++; // Here, we take the high byte of the register
// and we XOR it with the next 8 bits of data. Why?
x ^= x>>4; // Then, we XOR it with its last four bits?
// And we always remain with 4 possible non-zero bits, right?
// Why do we do this?
crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x <<5)) ^ ((uint16_t)x);
// Finally, we drop the oldest (highest) byte from the register
// And XOR it with rotations of x, according to the polynomial
// 0x1021, which is x^16 + x^12 + x^5 + 1
// Is (16-12) = 4 the reason why x has 4 possible non-zero bits?
I guess that this algorithm is just the equivalent of 8 loops of a bitwise algorithm but I would appreciate some clarification. Thanks for your time.