【问题标题】:CRC8 algorithm clarificationsCRC8算法说明
【发布时间】:2017-06-14 18:58:35
【问题描述】:

我偶然发现了这种 8 位 CRC 的实现:https://stackoverflow.com/a/15171925/243827

有人可以解释一下这张桌子是如何获得的吗?我已取消注释 crc8_slow 函数并尝试使用

  byte crc;
  byte data[1] = {0x01};
  crc = crc8_slow(0, data, sizeof(data)/sizeof(byte));
  printf("0x%.2X", crc);

对于 POLY 定义为 4d、d4、a6 或 b2。我似乎无法从该表中重现该值。另外,我如何需要为移位寄存器的非 0xff 初始值修改该代码?

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

运行时产生0x01。如果有关系,我在 Atmega 8 位上。

【问题讨论】:

  • “EDIT1”代码不能直接运行,但是当它可以运行时,它会给出0xB2。我必须添加一个typedef unsigned char byte;
  • @MarkAdler 不,将所有内容切换到 unsigned char - 结果相同
  • 您需要发布您运行的准确完整的代码。

标签: c xor crc binary-operators


【解决方案1】:

该表是单个字节 0..255 的 crc8_slow(),没有初始和最终异或。该代码已经将POLY 定义为0xb2,这是给定多项式的反映(0x4d 位反转)。

对于具有零初始寄存器值且没有最终异或的不同 CRC-8 定义,只需从代码中删除两个异或。

您可以查看 crcany 以生成任何给定规范的 CRC 代码。

【讨论】:

    【解决方案2】:

    Poly0x14D 反转,然后右移 1 位得到 0xB2。 crc 是bit reflected,它使用右移而不是左移。

    101001101      0x14d
    101100101      0x14d bit reversed = 0x165
     10110010      0x14d bit reversed >> 1 = 0xB2
    

    如果您查看crc8_table[0x80],您会看到0xB2。每行有 12 个字节长,并且由于索引 0x80 是十进制的 128,请查看以 0x1d 开头的第 10 行,然后查看字节 8(该行的第一个字节为 120),以查看 @987654331 @。

    我测试了这段代码,它打印了一个 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;
    }
    

    【讨论】:

    • 错误,有用且令人困惑:)。你能检查我的编辑吗?
    • 好的,这可能与我的 8 位架构有关。我会看到更多。谢谢!
    猜你喜欢
    • 2021-12-19
    • 2017-10-28
    • 2015-07-18
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    相关资源
    最近更新 更多