I want to implement CRC8 generator. CRC8-ATM works without problems. However, when using the polynomial of CRC8-MAXIM, the calculation result is different. Did I calculate the wrong way?
==============================
CRC8-ATM
dat: "AB" = 01000001 01000010
ply: 0x107 = 100000111
res: 0x87
==============================
01000001 01000010 00000000
1000001 11
----------------------------
10000010 00000000
10000011 1
----------------------------
1 1000000
1 00000111
----------------------------
my_res: 10000111 => 0x87 (OK)
==============================
CRC8-MAXIM
dat: "AB" = 01000001 01000010
ply: 0x131 = 100110001
res: 0xA5
==============================
01000001 01000010 00000000
1001100 01
----------------------------
1101 00000010 00000000
1001 10001
----------------------------
100 10001010 00000000
100 110001
----------------------------
1001110 00000000
1001100 01
----------------------------
10 01000000
10 0110001
----------------------------
my_res : 00100010 => 0x22 (Must be 0xA5)
For the calculation results, refer to the site below.
If anyone is familiar with the implementation of CRC8, please help.
Yes, there is.
Regular CRC-8 and CRC-8/MAXIM have different RefIn
and RefOut
configurations :
RefIn
parameter indicates if the data byte should be reversed before being used.RefOut
parameter indicates if the computed CRC should be reversed before appling the final XorOut
operation.Here is a piece of code computing CRC8 algorithms:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
uint8_t uint8_reverse(uint8_t val)
{
uint8_t ret = 0;
for (size_t i = 0; i < 8; i++)
{
if (val & 0x80)
{
ret |= (1 << i);
}
val <<= 1;
}
return ret;
}
uint8_t crc8(uint8_t const * data, size_t data_size, uint8_t poly, uint8_t init,
bool refin, bool refout, uint8_t xor_out)
{
uint8_t crc = init;
for (size_t i = 0; i < data_size; i++)
{
crc = crc ^ (refin ? uint8_reverse(data[i]) : data[i]);
for (size_t j = 0; j < 8; j++)
{
if (crc & 0x80)
{
crc = (crc << 1) ^ poly;
}
else
{
crc <<= 1;
}
}
}
return (refout ? uint8_reverse(crc) : crc) ^ xor_out;
}
int main(void)
{
printf("--- Check data ---\n");
const uint8_t check[9] = "123456789";
printf("crc8: 0x%02x\n", crc8(check, 9, 0x07, 0x00, 0, 0, 0x00));
printf("crc8-cdma2000: 0x%02x\n", crc8(check, 9, 0x9b, 0xff, 0, 0, 0x00));
printf("crc8-darc: 0x%02x\n", crc8(check, 9, 0x39, 0x00, 1, 1, 0x00));
printf("crc8-itu: 0x%02x\n", crc8(check, 9, 0x07, 0x00, 0, 0, 0x55));
printf("crc8-maxim: 0x%02x\n", crc8(check, 9, 0x31, 0x00, 1, 1, 0x00));
printf("--- 'AB' data ---\n");
const uint8_t ab_data[2] = "AB";
printf("crc8: 0x%02x\n", crc8(ab_data, 2, 0x07, 0x00, 0, 0, 0x00));
printf("crc8-itu: 0x%02x\n", crc8(ab_data, 2, 0x07, 0x00, 0, 0, 0x55));
printf("crc8-maxim: 0x%02x\n", crc8(ab_data, 2, 0x31, 0x00, 1, 1, 0x00));
return 0;
}
It outputs:
--- Check data ---
crc8: 0xf4
crc8-cdma2000: 0xda
crc8-darc: 0x15
crc8-itu: 0xa1
crc8-maxim: 0xa1
--- 'AB' data ---
crc8: 0x87
crc8-itu: 0xd2
crc8-maxim: 0xa5
Note that most of the time RefIn
and RefOut
have the same value, and code optimization is possible (i.e. avoiding all byte reversing operations).