我正在开发一个库,通过RS232或RS485连接提供简单可靠的通信.此代码的一部分涉及对数据使用CRC16校验和来检测线路噪声的损坏.我已经创建了一个计算CRC16校验和的函数,但它似乎没有输出正确的值.
我写的相关代码如下(也可以在这里找到).
#include <stdint.h>
#define CRC16 0x8005
uint16_t gen_crc16(const uint8_t *data, uint16_t size)
{
uint16_t out = 0;
int bits_read = 0, bit_flag;
/* Sanity check: */
if(data == NULL)
return 0;
while(size > 0)
{
bit_flag = out >> 15;
/* Get next bit: */
out <<= 1;
out |= (*data >> (7 - bits_read)) & 1;
/* Increment bit counter: */
bits_read++;
if(bits_read > 7)
{
bits_read = 0;
data++;
size--;
}
/* Cycle check: */ …Run Code Online (Sandbox Code Playgroud) 我有一个旧的,不再制造的带有串口的电子设备.我正在尝试对此设备中使用的数据包CRC /校验和/散列进行逆向工程.
任何有敏锐眼光,有敏锐数学技能的人都可以破解这个东西?
这是我到目前为止所知道的......
验证我的数据包样本观察到上述网络链接中概述的"叠加原则".这表明它们具有数学XOR关系.
开始感觉很好......但之后又难过了.无法确定CRC-16多项式.这些数据包哈希很可能不与CRC相关,而是一些家庭酿造方案.
通过Ross N. Williams阅读"CRC错误检测算法的无痛指南"
不幸的是,我无法访问任何设备源/二进制代码
还运行测试以查看是否使用了其他哈希,例如Fletcher的校验和
以下是我的数据包的各种样本.
0x47366B2EE00000000000751CEB5F3469543B585E2D
0x47366B2ED00000000000751CEB5F3469543B582A2C
0x47366B2EC80000000000751CEB5F3469543B580B2B
0x47366B2EC40000000000751CEB5F3469543B58BB2A
0x47366B2EC20040000000751CEB5F3469543B58DFE7
0x47366B2EC10000000000751CEB5F3469543B58A328
0x47366B2EC08000000000751CEB5F3469543B584127
0x47366B2EC04000000000751CEB5F3469543B588126
0x47366B2EC02000000000751CEB5F3469543B580525
0x47366B2EC01000000000751CEB5F3469543B580124
请注意以下有关这些数据包的信息......
(0X47)............................................... ......................(0x2D)
我不知道我的系统是大端还是小端,但是确定的字节是LSB优先的
请参阅数据包的0x47366B2E部分之后的数据字节.
只有模式我看到出现的是每个数据包上的最后一个字节递减一(2D,2C,...).(除了第5个数据包,我必须更改2位)
任何帮助表示赞赏!
我正在尝试使用C#生成CRC-16.我用于RS232的硬件要求输入字符串为HEX.下面的屏幕截图显示了正确的转换.对于测试,我需要8000为0xC061,但是生成CRC-16的C#方法必须能够转换任何给定的HEX字符串.

我尝试过使用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.IsNullOrEmpty(strInput) && strInput.Length …Run Code Online (Sandbox Code Playgroud) 我正在实现一个软件,我通过串口读取和写入Modbus RTU协议中的数据.为此,我需要在字节串的末尾计算两个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, …Run Code Online (Sandbox Code Playgroud) 我正在尝试将CRC16错误检测添加到Motorola HCS08微控制器应用程序中.但是,我的校验和不匹配.一个在线CRC计算器提供了我在PC程序中看到的结果和我在微观上看到的结果.
它调用micro的结果"XModem"和PC的结果"Kermit".
这两个古老的协议指定使用CRC16的方式有什么区别?
我正在使用 ModBus RTU,并且我正在尝试弄清楚如何计算 CRC16。我不需要代码示例。我只是对这个机制感到好奇。我了解到基本的 CRC 是数据字的多项式除法,根据多项式的长度用零填充。下面的测试示例应该检查我的基本理解是否正确:
计算。
01001011000
1001
0000011000
1001
01010
1001
0011
Run Code Online (Sandbox Code Playgroud)
Edit1:到目前为止已由 Mark Adler 在之前的评论/答案中验证。
在寻找答案时,我看到了很多不同的方法,包括反转、依赖小端或大端等,这些方法改变了给定的结果011。
Modbus RTU CRC16
当然,我很想了解不同版本的 CRC 是如何工作的,但我的主要兴趣是简单地了解这里应用的机制。到目前为止我知道:
我确实像上面的示例一样手动计算了这个值,但我不想在这个问题中以二进制形式写下来。我认为我的二进制转换是正确的。我不知道的是如何合并初始值——它是用来填充数据字而不是零吗?或者我需要颠倒答案吗?还有别的事吗?
第一次尝试:用 0 填充 16 位。计算出的二进制余数为1111 1111 1001 1011十六FF9B进制,对于 CrC16/Modbus 不正确,但对于 …
我需要帮助将用Ojective C编写的CRC代码转换为PHP.以下是Objective C代码
static UInt16 CRC16_Table[] =
{ 0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xa550, 0xc660, 0xe770,
0x0881, 0x2991, 0x4aa1, 0x6bb1, 0x8cc1, 0xadd1, 0xcee1, 0xeff1,
0x3112, 0x1002, 0x7332, 0x5222, 0xb552, 0x9442, 0xf772, 0xd662,
0x3993, 0x1883, 0x7bb3, 0x5aa3, 0xbdd3, 0x9cc3, 0xfff3, 0xdee3,
0x6224, 0x4334, 0x2004, 0x0114, 0xe664, 0xc774, 0xa444, 0x8554,
0x6aa5, 0x4bb5, 0x2885, 0x0995, 0xeee5, 0xcff5, 0xacc5, 0x8dd5,
0x5336, 0x7226, 0x1116, 0x3006, 0xd776, 0xf666, 0x9556, 0xb446,
0x5bb7, 0x7aa7, 0x1997, 0x3887, 0xdff7, 0xfee7, 0x9dd7, 0xbcc7,
0xc448, 0xe558, 0x8668, 0xa778, 0x4008, 0x6118, 0x0228, 0x2338, …Run Code Online (Sandbox Code Playgroud) 我正在尝试与某些系统接口,并且在他们的规范中,他们需要计算用于串行通信的CRC 16.以下是文档摘录
"利用标准多项式的消息的16位CCITT CRC,X16 + X12 + X5 + 1.种子值始终为0(零)"
首先,我只发现了2-3个C#代码示例,如何做到这一点似乎没有给我正确的值.我试过这个http://www.sanity-free.com/133/crc_16_ccitt_in_csharp.html,但我不确定要为初始值设置什么.我试了零但仍然无法正常工作.
我正在测试的数据是:
0x00 0x09 0x10 0x01 0x01 0x7C 0xF4 0xB8 0x00,
Run Code Online (Sandbox Code Playgroud)
我得到的CRC值是
0xF2 0x24,
Run Code Online (Sandbox Code Playgroud)
但他们的系统说它应该是
0xC0 0x2F
Run Code Online (Sandbox Code Playgroud)
我的理解是多项式x16 + x12 + x5 + 1 = 0x11021,但即使我在代码中使用它,它仍然给我错误的答案.我究竟做错了什么?
我正在尝试使用crcmod Python 模块和 2.7 版本的 Python 解释器基于CRC-16算法评估适当的校验和。校验和参数为:
代码:
crc16 = crcmod.mkCrcFun(0x18005, rev=False, initCrc=0xFFFF, xorOut=0x0000)
print hex(crc16(str(int(0x5A0001))))
Run Code Online (Sandbox Code Playgroud)
对于0x5A0001它打印的输入0x7E16,而我应该得到类似的东西0xCE0A。
我检查了http://www.lokker.net/Java/crc/CRCcalculation2.htm,计算出的值是0xACE正确的(相对于顺序)。