当前位置: 首页 > 知识库问答 >
问题:

如何配置CRC表的计算

訾高飞
2023-03-14
    null

编辑:我应该如何单独控制每一个参数?我想了解init函数实际上是如何工作的,以及所有参数是如何实现的。

typedef unsigned char uint8_t;
typedef unsigned short crc;

crc  crcTable[256];
#define WIDTH  (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
#define POLYNOMIAL 0x1021

template<typename t>
t reflect(t v)
{
    t r = 0;

    for (int i = 0; i < (8 * sizeof v); ++i)
    {
        r <<= 1;
        r |= v&1;
        v >>= 1;
    }

    return r;
}

void Init()
{
    crc  remainder;

    for (int dividend = 0; dividend < 256; ++dividend)
    {
        remainder = dividend << (WIDTH - 8);

        for (uint8_t bit = 8; bit > 0; --bit)
        {
            if (remainder & TOPBIT)
                remainder = (remainder << 1) ^ POLYNOMIAL;
            else
                remainder = (remainder << 1);
        }

        crcTable[dividend] = remainder;
    }
}

crc Calculate(const uint8_t *message, int nBytes, crc wOldCRC)
{
    uint8_t data;
    crc remainder = wOldCRC;

    for (int byte = 0; byte < nBytes; ++byte)
    {
        data = reflect(message[byte]) ^ (remainder >> (WIDTH - 8));
        remainder = crcTable[data] ^ (remainder << 8);
    }

    return reflect(remainder);
}

int main()
{
    crc expected = 0x6f91;
    uint8_t pattern[] = "123456789";

    Init();
    crc result = Calculate(pattern, 9, 0xFFFF);

    if (result != expected)
    {
        // this output is not relevant to the question, despite C++ tag
        printf("CRC 0x%04x wrong, expected 0x%04x\n", result, expected);
    }
}

共有1个答案

柴瀚
2023-03-14

而不是反映数据的进来,CRC的进来,CRC的出去,你只是反映多项式和运算。您只需要在编写代码时这样做一次。反射多项式为0x8408

typedef unsigned char uint8_t;
typedef unsigned short crc;

crc  crcTable[256];
#define POLYNOMIAL 0x8408

void Init()
{
    crc  remainder;

    for (int dividend = 0; dividend < 256; ++dividend)
    {
        remainder = dividend;

        for (uint8_t bit = 8; bit > 0; --bit)
        {
            if (remainder & 1)
                remainder = (remainder >> 1) ^ POLYNOMIAL;
            else
                remainder = (remainder >> 1);
        }

        crcTable[dividend] = remainder;
    }
}

crc Calculate(const uint8_t *message, int nBytes, crc wOldCRC)
{
    uint8_t data;
    crc remainder = wOldCRC;

    for (int byte = 0; byte < nBytes; ++byte)
    {
        data = message[byte] ^ remainder;
        remainder = crcTable[data] ^ (remainder >> 8);
    }

    return remainder;
}

int main()
{
    crc expected = 0x6f91;
    uint8_t pattern[] = "123456789";

    Init();
    crc result = Calculate(pattern, 9, 0xFFFF);

    if (result != expected)
    {
        // this output is not relevant to the question, despite C++ tag
        printf("CRC 0x%04x wrong, expected 0x%04x\n", result, expected);
    }
}

在一般情况下,如果输入数据被反射,则反射如下面答案所示的多项式,在底部输入字节,检查低位以排除多项式,并向上移位。如果输入数据没有反映出来,那么就像问题中的代码一样,保持多项式不变,在顶部输入字节,检查高位,然后向下移动。

在几乎所有情况下,输出的反射与输入的反射是相同的。对于所有这些,不需要一点反向函数。如果输入和输出都没有反映,或者输入和输出都反映,则保持移位寄存器的结果不变。在RevEng站点编目的72个CRC中,只有一个CRC-12/3GPP(CRC-12/3GPP)的反射out不同于反射In(CRC-12/3GPP)。在这种情况下,您需要对输出进行位反转,因为输入没有被反映,而输出却被反映。

 类似资料:
  • 我正试图从一个旧的串行设备反向工程通信协议。我已经搞清楚了大部分,但仍然停留在使用的CRC算法上。我有一个主机软件,我可以生成请求消息,所以我已经包括了一个由主机软件发送的相对较短的消息转储。 下面还有一些我还没有完全解码的数据字符串,前3个字符是从属地址(类似于modbus设备地址方案),接下来的2个字符是函数代码。“10”是一个数据缓冲区请求,我还没有解码。有趣的是,在这个特定的请求中有非数字

  • 我有一个通过RS232 COM与计算机通信的终端。我得到的协议说,我必须发送一定的字节组合和CRC 16 IBM计算的数据在最后发送 我还得到了一个C编写的应用程序,我可以用它来测试,该应用程序编写了一个带有发送数据和接收数据的日志。在该日志中,我查看是否向终端发送了以下字符串。我还必须发送数据06 35的这个CRC16 IBM结果。 我已经设法以某种方式将作为示例给出的C方法翻译成C#。但我的结

  • 问题内容: 我们有必要在哪里需要在表头上显示“隐藏/显示”列功能,并且还希望在ant设计中为表头提供不同的颜色。谁能帮助我,我们该怎么做?我没有找到任何控件可以执行此操作,因为标头渲染完全在组件内部。 问题答案: 您可以将该属性与普通CSS结合使用。

  • 因此,我的问题是:如何从整数结果到所需的双十六进制结果?我试了几个选择,都没有成功。 注意:我使用的是Qt,所以如果有人能找到实现QByteArray或其他Qt友好代码的解决方案,我会很高兴的。无论哪种方式,不使用Qt、C或C++的解决方案都是无用的:P

  • FF-源地址 53-数据 70-数据