c++ - CCITT CRC 16 位起始值 0xffff

标签 c++ checksum crc crc16

我需要计算作为参数传递的数据的 CCITT 16 位校验和值以及长度。如果我用测试数据“123456789”填充我的数组 TempStr,使用长度不包括空终止字符的多项式 0x8408,我得到结果字符串 6E90(十六进制)。连同空终止字符,我得到 907A。当我将多项式换成 0x1201 时,我得到结果 29E2(Hex) 和 EFE8(Hex),有和没有终止字符。

我的问题是: 我是否需要计算带有或不带有空终止字符的 CRC 以获得正确的值? 我在算法中使用多项式 0x1201 还是反向多项式 0x8408? 给定数据 0x29B1 的正确 CRC 校验是否正确?我需要正确的值来确定该功能是否正常工作.. 计算此特定 CRC 类型的算法是否正确? wData=(unsigned int)0xff & *pData++?? 如果有人可以向我解释哪里出了问题以及如何解决我的问题,我将不胜感激。 谢谢

这是使用和显示 calculate_CRC16 函数的代码:

CHAR_t TestStr[] = {"123456789"};
unsigned short CrcTest = calculate_CRC16(TestStr,sizeof(TestStr)-1);
QString CrcDisplay = QString("CrcTest : %1").arg(CrcTest);
ui->txtDebug->setText(CrcDisplay);

这是 calculate_CRC16 函数:

UINT16_t MainWindow::calculate_CRC16(CHAR_t* pData, UINT16_t wLength)
{

  UCHAR_t i;
  UINT16_t wData;
  UINT16_t wCrc = 0xffff;

  if (wLength == 0)
    return (~wCrc);

  do
  {
    for (i=0, wData=(unsigned int)0xff & *pData++; i < 8; i++, wData >>= 1)
    {
        if ((wCrc & 0x0001) ^ (wData & 0x0001))
            wCrc = (wCrc >> 1) ^ CRC_POLY;
        else  wCrc >>= 1;
    }
  } while (--wLength);

  wCrc = ~wCrc;
  wData = wCrc;
  wCrc = (wCrc << 8) | (wData >> 8 & 0xff);

  return (wCrc);
}

最佳答案

0x29b1 的结果是 "false" CCITT CRC-16 (链接到 CRC 目录)。这显然是你需要的。来自目录:

width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 name="CRC-16/CCITT-FALSE"

所以没有位反转(refin, refout false)。 CRC 用 0xffff 初始化,不进行后处理。

以最少的更改修复您的代码:

if (wLength == 0)
    return wCrc;

do
{
    for (i=0, wData=((unsigned int)0xff & *pData++) << 8; i < 8; i++, wData <<= 1)
    {

        if ((wCrc & 0x8000) ^ (wData & 0x8000))
            wCrc = (wCrc << 1) ^ 0x1021;
        else  wCrc <<= 1;
    }
} while (--wLength);

return wCrc & 0xffff;

或者更合理的做法:

while (wLength--) {
    wCrc ^= *(unsigned char *)pData++ << 8;
    for (i=0; i < 8; i++)
        wCrc = wCrc & 0x8000 ? (wCrc << 1) ^ 0x1021 : wCrc << 1;
}
return wCrc & 0xffff;

关于c++ - CCITT CRC 16 位起始值 0xffff,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21252069/

相关文章:

algorithm - 校验位算法 Luhn mod N 与简单和

javascript - CRC-16-IBM 实现 (JS) 不工作

c++ - 如何使用 IOCP 获取客户端真实 IP 地址和端口?

c++ - 字节顺序转换和 g++ 警告

c++ - 如何以打包的方式初始化布局,减少布局之间的空间?

ruby - 有没有一种快速简便的方法可以从 Ruby 的基本数据结构创建校验和?

c++ - 从文件读取时如何跳过数组的第一行?

c - C 中带环绕的 8 位校验和

java - java 中的 CRC-CCITT 验证 (android)

java - 将 C 源 CRC16CITT 函数转换为 Java