计算5位poly (0x15)的Crc



我有两个CrC需要解决。多项式长度:8位,隐含第9位1位多项式值:0x85初始值:0x00

多项式长度:5位,隐含第6位1位多项式值:0x15初始值:0x00

My first was very easy, with the following code. 
byte generator = 0x85;
byte crc = 0; /* start with 0 so first byte can be 'xored' in */
foreach (byte currByte in bytes)
{
crc ^= currByte; /* XOR-in the next input byte */
for (int i = 0; i < 8; i++)
{
if ((crc & 0x80) != 0)
{
crc = (byte)((crc << 1) ^ generator);
}
else
{
crc <<= 1;
}
}
}
return crc;

但是对于我的生命,我不明白5位是如何工作的。当然,生成器是0x15,但这在上面不起作用。我想也许我运行循环5次而不是8次,但这也没有得到它。

示例crc的多项式为0x15。0x80, 0x00应该得到0x01

的5bit CRC0x00, 0x20应该得到0x15的5bit CRC

0x01,0x00应该得到0x16的5bit CRC

0x01,0x20应该得到0x03的5bit CRC

0x01,0x40应该得到0x09

的5bit CRC0x01,0x60应该得到0x1c的5bit CRC

以便更好地理解这是如何工作的。有一个2字节的内存地址,每32字节步进一次。因为这5个额外的比特从来没有被使用过,所以crc就进入了它们。

内存地址0x0020示例

0000000000100000 (0 x20)

0x15的Or'd crc结果

0000000000010101 (0 x15)

=

0000000000110101 (0 x35)

所以我需要把我的地址0x0020,并得到一个crc 0x15回来。Crc的详细信息如上所述。它是一个经过验证的Crc,并在给定的应用程序中使用。

根据下面的建议,但没有得到我应该得到的结果。

byte generator = 0x15;
byte crc = 0; /* start with 0 so first byte can be 'xored' in */
foreach (byte currByte in bytes)
{
crc ^= currByte; /* XOR-in the next input byte */
for (int i = 0; i < 8; i++)
{
if ((crc & 0x80) != 0)
{
crc = (byte)((crc << 1) ^ (generator << 3));
}
else
{
crc <<= 1;
}
}
}
return (byte)(crc >>= 3);

您需要if ((crc & 0x20) != 0),并在最后crc &= 0x1f;去除多余的位,这些位在字节中向上移动。

您还需要排他或在CRC的正确位上的数据。

下面是C中的一个例子:

#include <stddef.h>
#include <stdint.h>
uint8_t crc5(uint8_t crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0;
crc <<= 3;
for (size_t i = 0; i < len; i++) {
crc ^= data[i];
for (unsigned k = 0; k < 8; k++) {
crc = crc & 0x80 ? (crc << 1) ^ 0xa8 : crc << 1;
}
}
crc >>= 3;
return crc;
}

更新:

OP更正了用于crc的数据。它是16位地址的前11位,后5位始终为零。然后,5位CRC替换发送的内容的低5个零。

在这种情况下,上面的例程可以用来检查消息,通过处理16位地址+ CRC作为两个字节。正确消息的结果将是零。例如,01 7c的CRC得到0

如果这个5位CRC总是在16位值的高11位上计算,那么这个例子将计算5位CRC并检查它:

#include <stdint.h>
uint16_t crc5h(uint16_t addr, int k) {
while (k--)
addr = addr & 0x8000 ? (addr << 1) ^ 0xa800 : addr << 1;
return addr >> 11;
}

当以低五位为零且k等于11的地址调用时,返回要插入的5位CRC。与结果CRC相异的地址是要发送的。如果该16位的消息被馈送给crc5h(),并且k等于16,则所有16位将被处理,并且如果消息被接收时没有错误,结果将始终为零。

最新更新