我正在尝试修改that段代码,使其适用于任意值和长度。
到目前为止我的修改:
public static int ModRTU_CRC(final byte[] buf, int crc)
{
final int len = buf.length;
for (int pos = 0; pos < len; pos++)
{
crc ^= buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--)
{ // Loop over each bit
if ((crc & 0x0001) != 0)
{ // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else
{
// Else LSB is not set
crc >>= 1; // Just shift right
}
}
}
// Note, this number has low and high bytes swapped, so use it
// accordingly (or swap bytes)
return crc;
}
我以下列方式测试我的代码:
final String a = "1101011011";
final String crc = "10011";
final int parsedA = Integer.parseInt(a, 2);
final ByteBuffer parsedBytes = ByteBuffer.allocate(4).putInt(parsedA);
final byte[] array = parsedBytes.array();
final int parsedCRC = Integer.parseInt(crc, 2);
System.out.println(Integer.toBinaryString(ModRTU_CRC(array, parsedCRC)));
我得到1000111101000101
,但正确的答案是11010110111110
。即使我交换字节,我也无法实现目标。你能帮帮我弄清楚我犯了什么错吗?
答案 0 :(得分:2)
你很困惑。您尝试的示例直接来自Ross William的CRC教程。您需要再次完整地阅读该教程,并且更加缓慢,随着时间的推移解决所有问题。
CRC和CRC多项式是两个不同的东西。您的10011
是教程中的CRC多项式,x 4 + x + 1。您的1101011011
就是消息。在本教程中,将消息除以CRC多项式附加的0000
的余数为1110
。 那是CRC。它是一个四位CRC,因为它使用四次多项式。
那么你认为你应该得到的是附加了CRC的消息,即11010110111110
。那不是CRC。这是附加了CRC的消息。附加的消息和CRC具有以下属性:如果将其除以CRC多项式,则将得到零余数。这是计算CRC后通常传输的内容。
由于某种原因,您尝试使用CRC例程执行此操作,该例程对 16 位CRC使用不同的多项式(0xA001
用于多项式x 16 + x 15 + x 2 +1,反转),将CRC多项式从教程中的示例提供给初始CRC应该进入的位置例程(回想一下CRC和CRC多项式是两个不同的东西),并提供一个10位的消息为32位。此外,您将以big-endian顺序呈现消息(假设您没有改变该字节缓冲区的顺序),它首先提供一堆零,并且您正在使用一次处理8位的例程,这使得不可能只处理十位。
你应该离开CRC例程,重新开始教程。