CCITT CRC 16位起始值0xffff

Rua*_*enk 5 c++ checksum crc crc16

我需要为作为参数传递的数据和长度计算CCITT 16位校验和值.如果我用测试数据"123456789"填充我的数组TempStr,使用多项式0x8408,其长度不包括空终止字符,我得到结果字符串6E90(十六进制).与null终止字符一起,我得到907A.当我将多项式换算为0x1201时,我得到带有和不带终止字符的结果29E2(十六进制)和EFE8(十六进制).

我的问题是:我是否需要使用或不使用空终止字符来计算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);
Run Code Online (Sandbox Code Playgroud)

这是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);
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ler 4

结果0x29b1“假”CCITT CRC-16(链接到 CRC 目录)。这显然是您需要的。从目录:

width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 name="CRC-16/CCITT-FALSE"
Run Code Online (Sandbox Code Playgroud)

所以不存在位反转(refin, refoutfalse)。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;
Run Code Online (Sandbox Code Playgroud)

或者更合理地做到这一点:

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