c-crc8 atm和crc8 maxim的计算方式有区别吗



我想实现CRC8生成器。CRC8-ATM工作正常。然而,当使用CRC8-MAXIM的多项式时,计算结果不同。我是不是计算错了?

==============================
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)

有关计算结果,请参阅下面的网站。

https://crccalc.com

如果有人熟悉CRC8的实现,请提供帮助。

是的。
常规CRC-8和CRC-8/MAXIM具有不同的RefInRefOut配置:

  • RefIn参数指示数据字节在使用前是否应反转
  • CCD_ 4参数指示在应用最终CCD_

下面是一段计算CRC8算法的代码:

#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%02xn", crc8(check, 9, 0x07, 0x00, 0, 0, 0x00));
printf("crc8-cdma2000: 0x%02xn", crc8(check, 9, 0x9b, 0xff, 0, 0, 0x00));
printf("crc8-darc:     0x%02xn", crc8(check, 9, 0x39, 0x00, 1, 1, 0x00));
printf("crc8-itu:      0x%02xn", crc8(check, 9, 0x07, 0x00, 0, 0, 0x55));
printf("crc8-maxim:    0x%02xn", crc8(check, 9, 0x31, 0x00, 1, 1, 0x00));
printf("--- 'AB' data ---n");
const uint8_t ab_data[2] = "AB";
printf("crc8:          0x%02xn", crc8(ab_data, 2, 0x07, 0x00, 0, 0, 0x00));
printf("crc8-itu:      0x%02xn", crc8(ab_data, 2, 0x07, 0x00, 0, 0, 0x55));
printf("crc8-maxim:    0x%02xn", crc8(ab_data, 2, 0x31, 0x00, 1, 1, 0x00));
return 0;
}

它输出:

--- 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

请注意,大多数时候RefInRefOut具有相同的值,并且代码优化是可能的(,即避免所有字节反转操作(。

如@lrntgr所述,CRC-8/MAXIM定义反映了输入位和结果CRC位。用反映的输入和输出重新进行记法:

==============================
CRC8-MAXIM
dat: "AB" reflected = 10000010 01000010
ply: 0x131 = 100110001
res: 0xA5
==============================
10000010 01000010 00000000
10011000 1
----------------------------
11010 11000010 00000000
10011 0001
----------------------------
1001 11010010 00000000
1001 10001
----------------------------
1011010 00000000
1001100 01
----------------------------
10110 01000000
10011 0001
----------------------------
101 01010000
100 110001
----------------------------
1 10010100
1 00110001
----------------------------
my_res :          10100101 => reflected 10100101 = 0xA5

对于这个特定的例子,反射的0xA5就是0xA5!因此,不幸的是,你看不到需要对《儿童权利公约》进行最后反思。但是,确实如此。再举一个例子来看看。

同样如前所述,实际计算不需要反映输入和输出位,而是可以通过反映多项式并向下而不是向上移位来具有完全相同的效果。代码是:

unsigned crc8maxim(unsigned char const *dat, size_t len) {
unsigned crc = 0;
for (size_t i = 0; i < len; i++) {
crc ^= dat[i];
for (unsigned k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8c : crc >> 1;
}
return crc;
}

其中0x8c0x31的反映,不包括x8的多项式位。

最新更新