【问题标题】:CRC implementing a specific polynomial. How does the polynomial relate to the polynomial used in code?CRC 实现一个特定的多项式。多项式与代码中使用的多项式有何关系?
【发布时间】:2019-02-05 13:04:14
【问题描述】:

我有以下 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 会怎样(我已经看到了),它代表什么多项式?

【问题讨论】:

    标签: c crc


    【解决方案1】:

    0x18 与多项式 X^8+X^5+X^4+X^0 有什么关系?

    由于代码是右移CRC,所以每个字节的“最高位”是bit 0而不是bit 7。poly需要从100110001反转到100011001,也就是0x119,右移后bit 0x119 的 0 被移出,因此可以使用 0x118 代替。如果反馈位为 1,则代码使用第二个 if 语句指向 (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;
    }
    

    【讨论】:

      【解决方案2】:

      那个 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 项。

      【讨论】:

        【解决方案3】:

        参考Wiki article on CRC,它是在达拉斯1-wire芯片中使用的crc8实现。请注意,多项式可以表示为 Normal、Reversed、Reciprocal 和 Reversed reciprocal 表示(另见Polynomial representations)。看来,它是省略了最高位的逆倒数表示。

        【讨论】:

          猜你喜欢
          • 2011-04-17
          • 1970-01-01
          • 2016-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多