CRC 实现特定的多项式。多项式与代码中使用的多项式有何关系?
CRC implementing a specific polynomial. How does the polynomial relate to the polynomial used in code?
我有以下CRC函数:
#define CRC8INIT 0x00
#define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0
// ----------------------------------------------------------------------------
uint8_t crc8 (uint8_t *data, uint16_t number_of_bytes_in_data)
{
uint8_t crc;
uint16_t loop_count;
uint8_t bit_counter;
uint8_t b;
uint8_t feedback_bit;
crc = CRC8INIT;
for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++) {
b = data[loop_count];
bit_counter = 8;
do {
feedback_bit = (crc ^ b) & 0x01;
if (feedback_bit == 0x01) {
crc = crc ^ CRC8POLY;
}
crc = (crc >> 1) & 0x7F;
if (feedback_bit == 0x01) {
crc = crc | 0x80;
}
b = b >> 1;
bit_counter--;
} while (bit_counter > 0);
}
return crc;
}
0x18与多项式X^8+X^5+X^4+X^0有什么关系?
X^8+X^5+X^4+X^0 = 100110001
0x18 = 00011000
如果我将 CRC8POLY 定义为 0xEA(我已经看到了),那会代表什么多项式呢?
该 CRC 代码写得相当奇怪,多项式应用于两个不同的地方,将位分开。也就是说,在 crc = crc ^ CRCPOLY
和有条件地 crc = crc | 0x80
。通常应该这样写:
unsigned crc8(unsigned char const *dat, size_t len) {
unsigned crc = 0;
for (size_t i = 0; i < len; i++) {
crc ^= dat[i];
for (int k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8c : crc >> 1;
}
return crc;
}
其中 0x8c
是多项式的反转,没有 x8 项。
How does 0x18 relate to the polynomial X^8+X^5+X^4+X^0?
由于代码是右移CRC,所以每个字节的"most significant bit"是bit 0,而不是bit 7。poly需要从100110001反转为100011001,即右移后的0x119 , 0x119 的第 0 位被移出,因此可以使用 0x118 代替。如果反馈位为 1,代码使用第二个 if 语句 to or in (0x100) >> 1 == 0x80。作为替代方案,由于 feedback_bit 为 0 或 1,则 (0-feeback_bit) 可以用作 poly 的掩码(假设二进制补码数学)而不是使用 if 语句。
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#define CRC8INIT 0x00
#define CRC8POLY 0x8c // 0x119 >> 1
uint8_t crc8 (uint8_t *data, uint16_t number_of_bytes_in_data)
{
uint8_t crc;
uint16_t loop_count;
uint8_t bit_counter;
uint8_t b;
uint8_t feedback_bit;
crc = CRC8INIT;
for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++) {
b = data[loop_count];
bit_counter = 8;
do {
feedback_bit = (crc ^ b) & 0x01;
crc = (crc >> 1) ^ ((0-feedback_bit) & CRC8POLY);
b = b >> 1;
bit_counter--;
} while (bit_counter > 0);
}
return crc;
}
参考Wiki article on CRC , it's crc8 realization as used in Dallas 1-wire chips. Note, that polinomial can be represented in Normal, Reversed, Reciprocal and Reversed reciprocal representations (see also Polynomial representations)。看起来,它是省略了最高位的反向倒数表示。
我有以下CRC函数:
#define CRC8INIT 0x00
#define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0
// ----------------------------------------------------------------------------
uint8_t crc8 (uint8_t *data, uint16_t number_of_bytes_in_data)
{
uint8_t crc;
uint16_t loop_count;
uint8_t bit_counter;
uint8_t b;
uint8_t feedback_bit;
crc = CRC8INIT;
for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++) {
b = data[loop_count];
bit_counter = 8;
do {
feedback_bit = (crc ^ b) & 0x01;
if (feedback_bit == 0x01) {
crc = crc ^ CRC8POLY;
}
crc = (crc >> 1) & 0x7F;
if (feedback_bit == 0x01) {
crc = crc | 0x80;
}
b = b >> 1;
bit_counter--;
} while (bit_counter > 0);
}
return crc;
}
0x18与多项式X^8+X^5+X^4+X^0有什么关系?
X^8+X^5+X^4+X^0 = 100110001
0x18 = 00011000
如果我将 CRC8POLY 定义为 0xEA(我已经看到了),那会代表什么多项式呢?
该 CRC 代码写得相当奇怪,多项式应用于两个不同的地方,将位分开。也就是说,在 crc = crc ^ CRCPOLY
和有条件地 crc = crc | 0x80
。通常应该这样写:
unsigned crc8(unsigned char const *dat, size_t len) {
unsigned crc = 0;
for (size_t i = 0; i < len; i++) {
crc ^= dat[i];
for (int k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8c : crc >> 1;
}
return crc;
}
其中 0x8c
是多项式的反转,没有 x8 项。
How does 0x18 relate to the polynomial X^8+X^5+X^4+X^0?
由于代码是右移CRC,所以每个字节的"most significant bit"是bit 0,而不是bit 7。poly需要从100110001反转为100011001,即右移后的0x119 , 0x119 的第 0 位被移出,因此可以使用 0x118 代替。如果反馈位为 1,代码使用第二个 if 语句 to or in (0x100) >> 1 == 0x80。作为替代方案,由于 feedback_bit 为 0 或 1,则 (0-feeback_bit) 可以用作 poly 的掩码(假设二进制补码数学)而不是使用 if 语句。
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#define CRC8INIT 0x00
#define CRC8POLY 0x8c // 0x119 >> 1
uint8_t crc8 (uint8_t *data, uint16_t number_of_bytes_in_data)
{
uint8_t crc;
uint16_t loop_count;
uint8_t bit_counter;
uint8_t b;
uint8_t feedback_bit;
crc = CRC8INIT;
for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++) {
b = data[loop_count];
bit_counter = 8;
do {
feedback_bit = (crc ^ b) & 0x01;
crc = (crc >> 1) ^ ((0-feedback_bit) & CRC8POLY);
b = b >> 1;
bit_counter--;
} while (bit_counter > 0);
}
return crc;
}
参考Wiki article on CRC , it's crc8 realization as used in Dallas 1-wire chips. Note, that polinomial can be represented in Normal, Reversed, Reciprocal and Reversed reciprocal representations (see also Polynomial representations)。看起来,它是省略了最高位的反向倒数表示。