- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在实现一个软件,我可以通过串口在 Modbus RTU 协议(protocol)中读取和写入数据。为此,我需要计算字节串末尾的两个 CRC 字节,但我无法做到这一点。
在网上搜索,我发现了两个似乎可以正确计算 CRC 的函数:
WORD CRC16 (const BYTE *nData, WORD wLength)
{
static const WORD wCRCTable[] = {
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };
BYTE nTemp;
WORD wCRCWord = 0xFFFF;
while (wLength--)
{
nTemp = *nData++ ^ wCRCWord;
wCRCWord >>= 8;
wCRCWord ^= wCRCTable[nTemp];
}
return wCRCWord;
} // End: CRC16
和
uint CRC16_2(QByteArray buf, int len)
{
uint crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (uint)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
return crc;
}
问题是我应该得到两个十六进制字节作为 CRC 数字,而这个函数返回一个整数值。例如,对于“01”(1 字节),我应该得到一个“7E80”而我得到“21695”,但我无法从这个到那个十六进制数据进行某种转换。
因此,我的问题是:如何从整数结果转换为所需的双十六进制结果?我尝试了几个选项,但没有成功。
注意:我正在使用 Qt,所以如果有人能找到实现 QByteArray 或其他 Qt 友好代码的解决方案,我将很高兴。无论哪种方式,不使用 Qt、C 或 C++ 的解决方案都是无用的:P
最佳答案
unsigned int CRC16_2(unsigned char *buf, int len)
{
unsigned int crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
return crc;
}
我自己有点菜鸟,butttt-
我使用了你提供的代码并亲自测试了它,正如你所说它不能正常工作,但后来我意识到它正在传递十六进制字符,所以我只是将 uint 更改为 char 并且它至少为我检查了。
我什至手动计算了一个样本来仔细检查。
关于c++ - 计算 Modbus RTU CRC 16,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19347685/
我已经搜索过,但无法找到有关它是什么以及如何计算的信息。 我不知道为什么这个问题被否决了。不是说清楚和编程有关吗?或者我应该问: # Or you can compute the running CR
如果我有一定数量的字节要串行传输,我如何确定使用哪个 CRC(CRC8、CRC16 等,基本上是多少位的 CRC?)并且错误检测百分比仍然很高?有这个公式吗? 最佳答案 从 CRC 长度的角度来看,适
这个问题在这里已经有了答案: Incremental Checksums (3 个答案) 关闭 8 年前。 如果我有子串 S0, S1, ... Sn 计算出的 CRCs C0, C1, ... C
我知道 CRC 是一个线性函数,这意味着 CRC(x xor y) = CRC(x) xor CRC(y),但我不知道如何证明 CRC 的这个属性。 有谁有想法吗? 非常感谢! 最佳答案 这通常不是真
我知道使用 CRC 的全部目的是进行错误检测,但我听说有人说除了错误检测之外,它还可以用来进行基本的错误纠正。我很好奇是否是这样,如果是这样,它有多强大?我的意思是,我们通常将 CRC 称为能够执行
我见过 8 位、16 位和 32 位 CRC。 在什么时候我需要跳转到更广泛的 CRC? 我的直觉 react 是它基于数据长度: 1-100 字节:8 位 CRC 101 - 1000 字节:16
我正在学习 CRC,搜索引擎和 SO 对此一无所知...... 为什么我们有“正态”、“逆向”和“倒数”多项式?是喜欢 Big Endian、Little Endian 还是其他什么? 最佳答案 CR
在学习计算机网络类(class)时,教授谈到了示例代码中两个有效代码字之间的汉明距离。我已经阅读了有关汉明距离的信息,从告诉 2 个字符串之间的差异距离的角度来看,这是有道理的。例如: Code Wo
我从Wikipedia知道CRC计算算法。关于RAR文件的结构我读过here 。例如有这样写: The file has the magic number of: 0x 52 61 72 21
我已经阅读了 CCITT 和 TI 关于 msp430 的文档。是否可以使用任何内置函数计算 MSP430F5438A 的 CRC?或者我是否必须为每个获取的数据计算 CRC。 最佳答案 可以使用软件
我尝试修改现有项目的 CRC 模块。目前它使用 CRC-16-CCITT。从代码中我知道它的多项式是0x11021,它的CRC-Table是: static const unsigned sh
使用线性反馈移位寄存器(LFSR)实现CRC生成有两种方法,如图所示。图中生成多项式的系数为100111,红色“+”圆圈为异或运算符。两者的初始化寄存器值都是 00000。 例如,如果输入数据比特流是
当数据长度不是4的倍数时,有没有办法通过表驱动的方式加快CRC校验过程?在我的问题中,有 226 位需要检查,并通过 CRC24Q 算法为此计算了 24 位校验和。 最佳答案 使用表格计算第一部分的c
我需要计算消息的 CRC 并将其放在该消息的开头,以便带有“前置”补丁字节的消息的最终 CRC 等于 0。我能够做到这在几篇文章的帮助下非常容易,但不适用于我的特定参数。问题是我必须使用给定的 CRC
我正在将一些从我自己的类中定义的对象保存到文件中。 (保存流数据)。 这一切都很好,但我希望能够在文件中存储该文件的 CRC 校验和。 然后,每当我的应用程序尝试打开文件时,它都可以读取内部存储的 C
我有一组受 16 位校验和保护的数据,需要更正。校验和位置是已知的,计算它们的确切区域以及用于计算它们的确切算法却未知。 16 位,最低有效位在前。我怀疑这是某种 16 位 CRC,但我无法找到实际计
我想使用Nucleo L053R8的crc计算单元计算3字节的CRC值。生成多项式如下:g(X)=x^24 + x^10 + x^9 + x^6 + x^4 + x^3 + x + 1 看来使用这个C
开始之前:我绝对是 JAVA 的初学者。我一直是一名 C++ 程序员。所以当我在这里做傻事时请告诉我! 我正在查询一个巨大的数据库并将该数据直接导出到一个 zip 文件中。我们在这里讨论的是 35GB
我有一些 C++ 代码,我正在将其移植到 C。当我在 C 代码中计算 CRC 时,出于某种原因,它返回错误的 CRC 值,而 C++ 代码运行良好。我是 C++ 的新手。我需要一些帮助来理解我在返回错
我有两个来源来计算看似相同的 crc 值。我不明白为什么“boost/crc.hpp”实现与“linux/lib/crc-ccitt.c”实现不同。 crc-ccitt.c boost 这是一个说明问
我是一名优秀的程序员,十分优秀!