我花了相当长的时间来确认用于两个设备之间的ASCII数据通信的CRC-8算法的类型。我已经确认CRC是在0x02开始的文本字节+下一个字节的数据上计算的。我所描述的一个设备的接口设计文档指定使用初始值为0xFF的0xEA多项式。下面是一个捕获消息的示例:
输入字节: 0x02 0x41
CRC结果: b10011011或0x9B
关于这个问题,我对一个典型的CRC算法的内部工作几乎一无所知。最初,我尝试对输入字节进行手工计算,以确认我在尝试代码解决方案之前对algo的理解。这涉及到使用我的0xFF初始值的第一个输入字节,然后跳到第二个输入字节继续XOR操作。
多次尝试通过典型的XOR操作来确认CRC,同时在每个步骤中将MSB从寄存器中移出,我永远无法得到我想要的结果。今天,我意识到0xEA多项式也被认为是0xD5聚的反向倒数,它有一个隐含的1+x^8,这是CRC-8算法中常用的。这一事实如何改变我手工计算CRC的方式?我读过这样的文章:在某些情况下,反向移动会导致右移,而不是左移?
发布于 2020-03-13 16:01:01
多项式是x^8+x^7+x^5+x^3+x^2+x+1,=>,01AF位,反转到x^8+x^7+x^6+x^5+x^3+x+1,=>,0x1EB。在移位之后执行条件XOR的示例代码,因此XOR值为0x1EB>>1 = 0xF5。可以使用256字节表查找来替换内环。
using System;
namespace crc8r
{
class Program
{
private static byte crc8r(byte[] bfr, int bfrlen)
{
byte crc = 0xff;
for (int j = 0; j < bfrlen; j++)
{
crc ^= bfr[j];
for (int i = 0; i < 8; i++)
// assumes twos complement math
crc = (byte)((crc>>1)^((0-(crc&1))&0xf5));
}
return crc;
}
static void Main(string[] args)
{
byte[] data = new byte[3] {0x02, 0x41, 0x00};
byte crc;
crc = crc8r(data, 2); // crc == 0x9b
Console.WriteLine("{0:X2}", crc);
data[2] = crc;
crc = crc8r(data, 3); // crc == 0x00
Console.WriteLine("{0:X2}", crc);
return;
}
}
}对于"EA",如果在移位之前多项式是XOR‘’ed,则使用0x1EB (或0x1EA,因为位0将被移除,并不重要)。移位前的XOR‘’ing需要9位,或者后移位or或XOR为0x80,而移位后的XOR‘’ing只需要8位。
移位前使用0x1eb的代码行示例:
crc = (byte)((crc^((0-(crc&1))&0x1eb))>>1);https://stackoverflow.com/questions/60662938
复制相似问题