I have stumbled upon this implementation of 8 bit CRC: https://stackoverflow.com/a/15171925/243827
Can someone shed some light on how that table was obtained ? I have uncommented the crc8_slow
function and tried feeding it with
byte crc;
byte data[1] = {0x01};
crc = crc8_slow(0, data, sizeof(data)/sizeof(byte));
printf("0x%.2X", crc);
for POLY
defined to 4d, d4, a6 or b2. I can't seem to reproduce the value from that table. Also, how do I need to modify that code for a non 0xff initial value of the shift register ?
EDIT1:
#define POLY 0xB2
byte crc;
byte data[1] = {0x80};
crc = crc8_slow(0, data, sizeof(data)/sizeof(byte));
printf("0x%.2X", crc);
byte crc8_slow(byte crc, byte *data, size_t len)
{
byte *end;
if (len == 0)
return crc;
// crc ^= 0xff;
end = data + len;
do {
crc ^= *data++;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
} while (data < end);
// return crc ^ 0xff;
return crc;
}
Yields 0x01
when ran. I am on an Atmega 8 bits should it matter.
Poly
is 0x14D
reversed, then shifted right 1 bit to get 0xB2
. The crc is bit reflected
, which uses right shifts instead of left shifts.
101001101 0x14d
101100101 0x14d bit reversed = 0x165
10110010 0x14d bit reversed >> 1 = 0xB2
If you look at crc8_table[0x80]
, you'll see a 0xB2
. Each row is 12 bytes long, and since index 0x80
is decimal 128
, look at the 10th row starting with 0x1d
, and look at byte 8 (first byte of that row is 120), to see the 0xB2
.
I tested this code and it prints a 0xB2:
#include <stdio.h>
typedef unsigned char byte;
#define POLY 0xB2
// prototype
byte crc8_slow(byte crc, byte *data, size_t len);
int main(){
byte crc;
byte data[1] = {0x80};
crc = crc8_slow(0, data, sizeof(data)/sizeof(byte));
printf("0x%.2X", crc);
return 0;
}
byte crc8_slow(byte crc, byte *data, size_t len)
{
byte *end;
if (len == 0)
return crc;
// crc ^= 0xff;
end = data + len;
do {
crc ^= *data++;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
} while (data < end);
// return crc ^ 0xff;
return crc;
}