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

Java 具有任意值和长度的CRC计算,java,crc,Java,Crc,我试图修改一段代码,使其能够处理任意的值和长度 我迄今为止的修改: 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 fo

我试图修改一段代码,使其能够处理任意的值和长度

我迄今为止的修改:

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;
}

我得到了
1000111101000101
,但正确的答案是
11010111110
。即使我交换字节,我也无法达到目标。你能帮我找出哪里出了错吗?

你很困惑。您尝试的示例直接来自Ross William的CRC教程。你需要把整个教程再读一遍,读得慢一点,边读边做

CRC和CRC多项式是两个不同的东西。您的
10011
是教程中的CRC多项式,x4+x+1。您的
1101011011
就是消息。根据本教程,将消息除以附加了CRC多项式的
0000
的剩余部分是
1110
。这就是CRC。它是一个四位CRC,因为它使用四次多项式

那么您认为应该得到附加了CRC的消息,即
11010111110
。这不是《儿童权利公约》。这是附加了CRC的消息。该消息和附加的CRC具有这样的特性:如果将其除以CRC多项式,则将得到零的余数。这就是通常在计算CRC后传输的内容

出于某种原因,您正试图使用一个CRC例程执行此操作,该例程对16位CRC使用不同的多项式(
0xA001
用于多项式x16+x15+x2+1,反向),将教程中示例中的CRC多项式馈送到例程中初始CRC应该到达的位置(回想一下,CRC和CRC多项式是两个不同的东西),并将10位消息作为32位提供。此外,您以大端顺序呈现消息(假设您没有更改该字节缓冲区的顺序),它首先提供一组零,并且您使用的例程一次处理八位,这使得仅处理十位是不可能的


您应该远离CRC例程,重新开始本教程。

在链接代码中,
CRC
从0xFFFF开始,但在这里它从我们在代码中看不到的其他值开始(取决于
b
的值)。这是否正确?正确,crc取决于b的值。在这种情况下,
crc
将是
0x13
。问题中的代码没有显示
b
的值,因此您可能需要添加该值。此外,您如何计算
11010111110
是正确答案?此外,除了
c的起始值之外rc
,此代码与链接代码之间是否有任何差异?哎呀,
crc
意味着
b
。修复了:
final int parsedCRC=Integer.parseInt(crc,2)
我在一张纸上计算了
11010111110
1110
是通过
10011
除法的余数
1101011011
。有两个区别:我从缓冲区本身获得缓冲区的长度。加上crc不是固定的,我将它传递给方法。crc不是除法的余数。另外,你也没有打印
a
,仅计算出的CRC,因此即使它返回
1110
,它也只打印
1110
,而不打印
11010111110
。感谢您的冗长解释。我现在明白了,我修改并希望应用于各种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)));