早上好!
对于无线应用,我需要实现各种CRC计算。根据规范,CRC计算应作为移位寄存器实现。查看 EPC 规范
Ross N. Williams 有一本名为"CRC 错误检测算法的无痛指南"的优秀指南,其中包括我想使用的通用 C 实现。(包括源代码的链接(
问题是包含的函数只接受完整的字节作为输入。我的消息可以有不同的长度。
以下是添加字节的代码:
void cm_nxt(p_cm,ch)
p_cm_t p_cm;
int ch;
{
int i;
ulong uch = (ulong)ch;
ulong topbit = BITMASK(p_cm->cm_width - 1);
if (p_cm->cm_refin) uch = reflect(uch, 8);
p_cm->cm_reg ^= (uch << (p_cm->cm_width - 8));
for (i = 0; i <8; i++) {
if (p_cm->cm_reg & topbit)
p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
else
p_cm->cm_reg <<= 1;
p_cm->cm_reg &= widmask(p_cm);
}
}
现在我想实现一个函数,只是为了在计算中添加一个位。我尝试了以下代码:
void cm_nxt_bit(p_cm, ch)
p_cm_t p_cm;
int ch;
{
ulong uch = (ulong)ch;
ulong topbit = BITMASK(p_cm->cm_width - 1);
if (p_cm->cm_refin) uch = reflect(uch, 8);
p_cm->cm_reg ^= (uch << (p_cm->cm_width - 8));
if (p_cm->cm_reg & topbit)
p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
else
p_cm->cm_reg <<= 1;
p_cm->cm_reg &= widmask(p_cm);
}
不幸的是,它没有按预期工作。你能帮我实现这样的功能吗?
您需要将一位放在寄存器的顶部,就像其他代码将一个字节放在寄存器的顶部一样。假设ch
必须是0
或1
,因此您要添加的位是ch
的底部位,然后您需要将uch
上移cm_width-1
,而不是在独占或进入寄存器之前cm_width-8
。
也摆脱了reflect
的使用。一位的反射是相同的一位。
你也可以看看我的crcany代码,它为任何CRC定义生成C语言的CRC代码,包括一个例程,如果它不是长度的八位的倍数,它将计算流的最后1到7位的CRC。