计算 5 位多边形 (0x15) 的 Crc
Caculating Crc for 5 bit poly (0x15)
我有两个 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 次,但这也没有得到它。
多项式 0x15 的 CRC 示例。
0x80, 0x00 应该得到 0x01
的 5bit crc
0x00、0x20 应该得到 0x15 的 5 位 crc
0x01,0x00 应该得到 0x16 的 5 位 crc
0x01,0x20 应该得到 0x03 的 5 位 crc
0x01,0x40 应该得到 0x09 的 5 位 crc
0x01,0x60 应该得到 0x1c 的 5 位 crc
为了更好地理解这个 works.There 是一个每 32 字节步进的 2 字节内存地址。由于从未使用过 5 个额外的位,因此 crc 进入其中。
内存地址示例0x0020
0000000000100000 (0x20)
或0x15的crc结果
0000000000010101 (0x15)
=
0000000000110101 (0x35)
所以我需要获取我的地址 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 替换发送的那些低五个零。
在这种情况下,可以使用上述例程来检查消息,将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的地址调用时,返回要插入的五位CRC。与结果 CRC 异或的地址是要发送的内容。如果将该 16 位消息馈送到 crc5h()
,并且 k
等于 16,则将处理所有 16 位,如果消息没有错误地收到,结果将始终为零。
我有两个 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 次,但这也没有得到它。
多项式 0x15 的 CRC 示例。 0x80, 0x00 应该得到 0x01
的 5bit crc0x00、0x20 应该得到 0x15 的 5 位 crc
0x01,0x00 应该得到 0x16 的 5 位 crc
0x01,0x20 应该得到 0x03 的 5 位 crc
0x01,0x40 应该得到 0x09 的 5 位 crc
0x01,0x60 应该得到 0x1c 的 5 位 crc
为了更好地理解这个 works.There 是一个每 32 字节步进的 2 字节内存地址。由于从未使用过 5 个额外的位,因此 crc 进入其中。
内存地址示例0x0020
0000000000100000 (0x20)
或0x15的crc结果
0000000000010101 (0x15)
=
0000000000110101 (0x35)
所以我需要获取我的地址 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 替换发送的那些低五个零。
在这种情况下,可以使用上述例程来检查消息,将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的地址调用时,返回要插入的五位CRC。与结果 CRC 异或的地址是要发送的内容。如果将该 16 位消息馈送到 crc5h()
,并且 k
等于 16,则将处理所有 16 位,如果消息没有错误地收到,结果将始终为零。