天道酬勤,学无止境

CCITT CRC 16 位起始值 0xffff(CCITT CRC 16 Bit Start Value 0xffff)

问题

我需要计算作为参数与长度一起传递的数据的 CCITT 16 位校验和值。 如果我用测试数据“123456789”填充我的数组 TempStr,使用长度不包括空终止字符的多项式 0x8408,我得到结果字符串 6E90(Hex)。 连同空终止字符,我得到 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);
}
回答1

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

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

因此,有没有位反转( refinrefout假)。 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;
回答2

如果您查看一下,它将计算不同字符串(或十六进制序列,用于检查是否使用 NUL)的 CRC http://www.lammertbies.nl/comm/info/crc-calculation.html

据此,您不应该计算包括终止零来获得 0x29B1 的值进行计算。

由于您从低位开始,您应该使用“非反向”多项式。

我认为问题在于您在计算中移动“wCrc”时移动方式错误。

换句话说:

wCrc = (wCrc >> 1) ^ CRC_POLY;

应该:

wCrc = (wCrc << 1) ^ CRC_POLY;

同样:

wCrc >>= 1;

应该:

wCrc <<= 1;

但是,我不是 100% 确定。

回答3

CRC 算法有许多不同的变体。

  • 逐位计算与查找表
  • 反射字节与非反射字节(MSbit 或 LSbit 在前)。
  • 在消息末尾附加增强位,或者不附加。

最后一点是一个混乱的问题。 回到CRC理论,CRC可以看作GF(2)中的长除法,其结果是长除法的余数。 为了根据基础理论进行正确的计算,必须在消息末尾附加n 个零位以获得正确的答案。 有 CRC 算法以这种方式进行计算。

但是,更常见的 CRC 算法是以不同的方式完成的,因此消息不需要在消息末尾附加零位。 这种计算通常被称为“直接算法”。 除了需要修改算法的任何“初始值”以考虑这种变体算法之外,它使用起来更方便,并且在功能上等效。

在 CRC-16/CCITT 的情况下,这会导致对正确初始值的混淆:它应该是0xFFFF还是0x1D0F ? 可以说, 0xFFFF是将增强位附加到消息的算法的正确初始值。 如果使用“直接算法”,则必须将初始值设置为0x1D0F才能获得相同的结果。

因此,您需要了解这种差异,并使用需要的任何一种来与您所连接的程序/系统进行交互。

进一步阅读:

  • CRC-CCITT -- 16 位(其他来源)
  • 第 10 章,“稍微错位的表驱动实现”,Ross Williams 的 CRC 错误检测算法无痛指南
  • 参数化 CRC 算法目录中的 CRC-16/AUG-CCITT 与 CRC-16/CCITT-FALSE
  • 在线 CRC 计算器,允许使用“非直接”和“直接”算法进行计算,并在这两种算法之间转换初始值。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • CCITT CRC 16 Bit Start Value 0xffff
    I need to calculate a CCITT 16 bit checksum value for data passed as a parameter together with the length. If I fill my array TempStr with the test data "123456789", use the polynomial 0x8408 with the length excluding the null termination character, I get the result string 6E90(Hex). Together with the null termination char I get 907A. When I swap out the polynomial to 0x1201 then I get results 29E2(Hex) and EFE8(Hex) with and without termination character. My questions are: Do I need to calculate the CRC with or without the null termination character to obtain the correct value? Do I use the
  • CRC16算法之一:CRC16-CCITT-FALSE算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言JDK里包含了CRC32的算法,但是没有CRC16的,网上搜了一堆没有找到想要的,索性自己实现注意:CRC16算法分为很多种,本篇文章中,只讲其中的一种:CRC16-CCITT-FALSE算法CRC16算法系列之一:CRC16-CCITT-FALSE算法的java实现功能1、支持short类型2、支持int类型3、支持数组任意区域计算实现/** * crc16-ccitt-false加密工具 * * @author eguid * */public class CRC16 { /** * crc16-ccitt-false加/解密(四字节) * * @param bytes * @return */public static int crc16(byte[] bytes) {return crc16(bytes, bytes.length); } /** * crc16-ccitt-false加/解密(四字节) * * @param bytes -字节数组 * @return */public static int crc16
  • CRC16算法之一:CRC16-CCITT-FALSE算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言 JDK里包含了CRC32的算法,但是没有CRC16的,网上搜了一堆没有找到想要的,索性自己实现注意:CRC16算法分为很多种,本篇文章中,只讲其中的一种:CRC16-CCITT-FALSE算法CRC16算法系列之一:CRC16-CCITT-FALSE算法的java实现功能1、支持short类型2、支持int类型3、支持数组任意区域计算实现/** * crc16-ccitt-false加密工具 * * @author eguid * */ public class CRC16 { /** * crc16-ccitt-false加/解密(四字节) * * @param bytes * @return */ public static int crc16(byte[] bytes) { return crc16(bytes, bytes.length); } /** * crc16-ccitt-false加/解密(四字节) * * @param bytes -字节数组 * @return */ public static int
  • 将 C CRC16 转换为 Java CRC16(Convert C CRC16 to Java CRC16)
    问题 我目前正在做一个项目,有一个嵌入式系统通过无线电向 PC 发送数据。 数据包最后得到一个 crc16 校验和,它是根据这个算法计算的: uint16_t crc16 (const uint8_t * buffer, uint32_t size) { uint16_t crc = 0xFFFF; if (buffer && size) while (size--) { crc = (crc >> 8) | (crc << 8); crc ^= *buffer++; crc ^= ((unsigned char) crc) >> 4; crc ^= crc << 12; crc ^= (crc & 0xFF) << 5; } return crc; } 现在我正在寻找 Java 中的等价物。 我已经在这里找到了一个很好的:http://introcs.cs.princeton.edu/java/51data/CRC16CCITT.java.html public class CRC16CCITT { public static void main(String[] args) { int crc = 0xFFFF; // initial value int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) // byte
  • CRC-CCITT (0xFFFF) function?
    Can someone help me with Delphi implementation of CRC-CCITT (0xFFFF)? Already get the Java version, but confusing on how to port it to Delphi public static int CRC16CCITT(byte[] bytes) { int crc = 0xFFFF; // initial value int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) for (byte b : bytes) { for (int i = 0; i < 8; i++) { boolean bit = ((b >> (7-i) & 1) == 1); boolean c15 = ((crc >> 15 & 1) == 1); crc <<= 1; if (c15 ^ bit) crc ^= polynomial; } } crc &= 0xffff; //System.out.println("CRC16-CCITT = " + Integer.toHexString(crc)); return crc; } and for PHP implementation <?php function
  • 我如何猜测校验和算法?(How could I guess a checksum algorithm?)
    问题 假设我有一些数据包的末尾带有16位校验和。 我想猜测使用哪种校验和算法。 首先,从转储数据中,我可以看到数据包有效负载中的一个字节变化完全改变了校验和,因此我可以假定它不是某种简单的XOR或求和。 然后,我尝试了几种CRC16的变体,但运气不佳。 这个问题可能更偏向于密码学,但是我对任何易于理解的统计工具来找出这可能是CRC感兴趣。 如果其他所有方法都失败了,我什至可以转向绘制不同的CRC算法。 背景故事:我有带有某种校验和的串行RFID协议。 我可以毫无问题地重放消息,并解释结果(不进行校验和检查),但是由于设备将其丢在了地板上,所以我无法发送修改后的数据包。 使用现有软件,我可以更改RFID芯片的有效载荷。 但是,唯一的序列号是不可变的,因此我无法检查所有可能的组合。 尽管我可以生成递增1的值的转储,但不足以使详尽搜索适用于此问题。 如果问题本身还不够,则可以使用带有数据的转储文件:-) 需要参考文件吗? CRC错误检测算法的无忧指南是很好的参考,我在这里提出问题后就找到了。 最后,在给出了可接受的答案(比CCITT有用的提示)之后,我使用了此CRC计算器,并将生成的校验和与已知的校验和进行异或运算,得到0xffff,这使我得出结论:最终的xor是CCITT的0x0000的instread的0xffff。 回答1 CRC有很多变量需要考虑: Polynomial No
  • Calculation of CCITT standard CRC with polynomial x^16 + x^12 + x^5 + 1 in Java
    I need help with calculating of CCITT standard CRC with polynomial x^16 + x^12 + x^5 + 1 (0x1081) in Java. I have tried many examples on the internet but every one of them returns other values than the ones in the example. For example for this array [0xFC] [05] [11] the result needs to be [27] [56]. Using this code: public static void main(String[] args) { byte[] array = new byte[3]; array[0] = (byte) 0xFC; array[1] = (byte) 0x05; array[2] = (byte) 0x11; // array[3] = (byte) 0x00; // array[4] = (byte) 0x00; System.out.println(Integer.toHexString(crc16(array))); } private static final int
  • 如何在 PHP HEX 中计算 CRC16 CCITT?(How to calculate CRC16 CCITT in PHP HEX?)
    问题 我正在尝试使用 PHP CRC16 CCITT 函数来计算校验和。 设备向我发送了一个包含校验和的 PACKET: 10 00 00 00 00 00 00 00 12 51 09 08 00 18 00 04 02 14 00 0c 00 0c 02 1c 00 02 00 00 00 00 00 7 00 a 0 校验和在最后: a0 77 我试过使用 如何在php中计算crc16 为 CRC16 函数将 C 转换为 PHP 没有成功,CRC 16 计算返回: E6 F4而不是a0 77 查找时,我返回了正确的十六进制信息: 100000000000000012510908001800040214000c000c021c0002000000000000 在网站 http://www.lammertbies.nl/comm/info/crc-calculation.html 上,但我无法重现它。 (确保选择输入类型为HEX) 你能帮我弄清楚如何获得十六进制值字符串的 crc16 CCITT 100000000000000012510908001800040214000c000c021c0002000000000000 我正在寻找校验和a0 77 回答1 我能够使用如下实现生成相同的校验和: define('CRC16POLYN', 0x1021); function
  • Android CRC-CCITT
    I need a CRC check for an application Im writing, but cant figure out for the online code and calculators what im doing wrong. I may just not understand it correctly. This is what I need : It uses CRC-CCITT with a starting value of 0xFFFF with reverse input bit order. For example, the Get Device Type message is: 0x01, 0x06, 0x01, 0x00, 0x0B, 0xD9. The CRC is 0xD90B. And this is the code Im using : public static int CRC16CCITT(byte[] bytes) { int crc = 0xFFFF; // initial value int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) for (byte b : bytes) { for (int i = 0; i < 8; i++) { boolean
  • CRC-CCITT 到 CRC16 Modbus 实现(CRC-CCITT to CRC16 Modbus implementation)
    问题 我在使用 PHP 生成 modbus CRC16 代码时遇到了很多麻烦。 我在互联网上找到了很多不同的代码,但我已经尝试过,但由于某种原因我没有得到正确的结果。 我找到了一个用于生成 CRC16-CCITT 的 PHP 代码。 我已将查找表更改为 modbus CRC 对应表,但结果仍然不正确。 代码如下。 我还需要做什么才能将 CRC16-CCITT 代码转换为 CRC16-MODBUS 代码。 <?php /************************************************************************* * phpCrc16 v1.1 -- CRC16/CCITT implementation * * By Matteo Beccati <matteo@beccati.com> * * Original code by: * Ashley Roll * Digital Nemesis Pty Ltd * www.digitalnemesis.com * ash@digitalnemesis.com * * Test Vector: "123456789" (character string, no quotes) * Generated CRC: 0x29B1 * *****************************
  • CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现
    CRC16算法系列文章:CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言CRC16算法有很多种,本篇文章会介绍其中的CRC16-CCITT-XMODEM算法 功能实现CRC16-CCITT-XMODEM算法支持int、short类型支持选择数组区域计算实现package cc.eguid.crc16; /** * crc16多项式算法 * @author eguid * */ public class CRC16 { /** * CRC16-XMODEM算法(四字节) * @param bytes * @return */ public static int crc16_ccitt_xmodem(byte[] bytes) { return crc16_ccitt_xmodem(bytes,0,bytes.length); } /** * CRC16-XMODEM算法(四字节) * @param bytes * @param offset * @param count * @return */ public static int crc16_ccitt_xmodem(byte[] bytes,int
  • Convert C CRC16 to Java CRC16
    I am currently working on a project, having an embedded system sending data to a PC via radio. The packets get a crc16 checksum at the end and it's calculated based on this algorithm: uint16_t crc16 (const uint8_t * buffer, uint32_t size) { uint16_t crc = 0xFFFF; if (buffer && size) while (size--) { crc = (crc >> 8) | (crc << 8); crc ^= *buffer++; crc ^= ((unsigned char) crc) >> 4; crc ^= crc << 12; crc ^= (crc & 0xFF) << 5; } return crc; } Now I am looking for an equivalent in Java. I already found a good one here: http://introcs.cs.princeton.edu/java/51data/CRC16CCITT.java.html public class
  • CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 前言CRC16算法有很多种,本篇文章会介绍其中的CRC16-CCITT-XMODEM算法 功能实现CRC16-CCITT-XMODEM算法支持int、short类型支持选择数组区域计算实现package cc.eguid.crc16; /** * crc16多项式算法 * @author eguid * */public class CRC16 { /** * CRC16-XMODEM算法(四字节) * @param bytes * @return */public static int crc16_ccitt_xmodem(byte[] bytes) {return crc16_ccitt_xmodem(bytes,0,bytes.length);} /** * CRC16-XMODEM算法(四字节) * @param bytes * @param offset * @param count * @return */public static int crc16_ccitt_xmodem(byte[] bytes,int
  • 如何配置CRC表的计算(How to configure calculation of CRC table)
    问题 那里有很多CRC计算示例。 带有位移的简单实现,并通过预先计算的表更有效。 但是多项式旁边还有很多CRC参数会影响计算。 您可以在此处评估这些参数:http://zorc.breitbandkatze.de/crc.html 这些参数是 CRC的初始值输入数据的反映反映输出数据 CRC的最终XOR值 对于某些“标准” CRC算法,这些参数已很好定义,例如CRC-16(CCITT)。 但是有些实现使用不同的参数。 我的实现必须与CCITT多项式(x 16 + x 12 + x 5 +1)的CRC16兼容。 但是必须反映数据字节和最终的CRC。 我已经在计算方法中实现了这些反射。 但这很耗时。 为了获得最佳性能,必须将其从计算中删除。 在初始化方法中如何计算CRC的反射参数? 编辑:我应该怎么做才能分别控制每个参数? 我想了解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)
  • CRC-CCITT to CRC16 Modbus implementation
    I am having a lot of trouble on generating a modbus CRC16 code using PHP. I have found a lot of different codes over the internet but i have tried them and for some reason i didnt get right results. I have found a PHP code for generating CRC16-CCITT. I have chenge the look up table to the modbus CRC corresponding table but the result is still not the right one. The code is bellow. What do i need to do more in order to transform a CRC16-CCITT code into CRC16-MODBUS code. <?php /************************************************************************* * phpCrc16 v1.1 -- CRC16/CCITT
  • CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现
    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 功能实现CRC16-CCITT-MODBUS算法支持int、short类型支持选择数组区域计算实现/** * crc16_ccitt_modbus算法(四字节)友情提示:做好自己!--eguid博客地址:http://blog.csdn.net/eguid_1 * @param buf * @param offset * @param length * @return */public static int crc16_ccitt_modbus(byte[] buf,int offset, int length) {int i, j;int c, crc = 0xFFFF;for (i = offset; i < length; i++) {c = buf[i] & 0x00FF;crc ^= c;for (j = 0; j < 8; j++) {if ((crc & 0x0001) != 0) {crc >>= 1;crc ^= 0xA001;} elsecrc >>= 1;}}return crc;} /** * crc16
  • CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现
    CRC16算法系列文章:CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现 功能 实现CRC16-CCITT-MODBUS算法支持int、short类型支持选择数组区域计算实现 /** * crc16_ccitt_modbus算法(四字节)友情提示:做好自己!--eguid博客地址:http://blog.csdn.net/eguid_1 * @param buf * @param offset * @param length * @return */ public static int crc16_ccitt_modbus(byte[] buf,int offset, int length) { int i, j; int c, crc = 0xFFFF; for (i = offset; i < length; i++) { c = buf[i] & 0x00FF; crc ^= c; for (j = 0; j < 8; j++) { if ((crc & 0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else crc >>= 1; } } return crc
  • How could I guess a checksum algorithm?
    Let's assume that I have some packets with a 16-bit checksum at the end. I would like to guess which checksum algorithm is used. For a start, from dump data I can see that one byte change in the packet's payload totally changes the checksum, so I can assume that it isn't some kind of simple XOR or sum. Then I tried several variations of CRC16, but without much luck. This question might be more biased towards cryptography, but I'm really interested in any easy to understand statistical tools to find out which CRC this might be. I might even turn to drawing different CRC algorithms if everything
  • How to configure calculation of CRC table
    There are a lot of CRC calculation examples out there. Simple implementations with bit shifting and more efficient with a pre-calculated table. But there are also a lot of Parameters of a CRC beside the polynomial that affect the calculation. You can evaluate these parameters here: http://zorc.breitbandkatze.de/crc.html These parameters are initial value of CRC reflection of input data reflection of output data final XOR value for CRC For some "standard" CRC algorithm these parameters are well defined, like CRC-16 (CCITT). But there are some implementations that use different parameters. My
  • 如何从C#生成CRC-16(How to generate a CRC-16 from C#)
    问题 我正在尝试使用C#生成CRC-16。 我用于RS232的硬件要求输入字符串为十六进制。 下面的屏幕截图显示了正确的转换,对于测试,我需要8000为0xC061,但是生成CRC-16的C#方法必须能够转换任何给定的十六进制字符串。 我尝试使用Nito.KitchenSink.CRC 我也尝试了以下在输入8000时生成8009的方法- public string CalcCRC16(string strInput) { ushort crc = 0x0000; byte[] data = GetBytesFromHexString(strInput); for (int i = 0; i < data.Length; i++) { crc ^= (ushort)(data[i] << 8); for (int j = 0; j < 8; j++) { if ((crc & 0x8000) > 0) crc = (ushort)((crc << 1) ^ 0x8005); else crc <<= 1; } } return crc.ToString("X4"); } public Byte[] GetBytesFromHexString(string strInput) { Byte[] bytArOutput = new Byte[] { }; if (!string