具有任意值和长度的CRC计算

时间:2014-03-30 09:46:07

标签: java crc

我正在尝试修改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。即使我交换字节,我也无法实现目标。你能帮帮我弄清楚我犯了什么错吗?

1 个答案:

答案 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例程,重新开始教程。