我的CRC算法有什么问题?(爪哇)



昨天问了一个更广泛的问题,但我认为删除它并缩小我的问题范围可能是谨慎的。同样,为了诚实,是的,这是家庭作业。我正在尝试使用以下多项式开发CRC算法:

x15+x13+x6+x4+x1+1

我应该传递两个字节(8 位

),将它们组合成一个 16 位的结果(所以我将第一个字节向左移动 8,然后将两个字节加在一起),然后使用上述多项式找到 CRC。我一直在使用此工具检查我的输出应该是什么,但我似乎无法得到正确的答案。

我有什么:

(相关全局变量)

static String binaryCRC = "1010000001010011";
static long divisor = Long.parseLong(binaryCRC, 2);
static int mask = 0x8000;

(实际算法)

public static void crc(byte first, byte second) {
    long total = ((first << 8) + second);
    System.out.print(Long.toHexString(total));
    for (int i = 0; i < binaryCRC.length(); i++) {
        if ((total & mask) == mask) {
            total ^= divisor;
        }
        total <<= 1;
    }
    System.out.println(" -> " + Long.toHexString(total));
}

编辑:我尝试利用下面给出的建议修改我的 for 循环:

for (int i = 0; i < binaryCRC.length(); i++) {
        if ((total & mask) == mask) {
            total = (total << 1) ^ divisor;
        } else {
            total <<= 1;
        }
    }

也许我做错了,但是当我这样做时,我的输出变得非常遥远。当将我的两个字节的值设置为字符"a"和"b"的 ASCII 值(总计 = 6162)时,我得到 6162 -> 4f1b065d,而我应该得到 77eb。

编辑2:我在下面简要概述了它,但为了清楚起见,我添加了我需要做的其余内容,因为我不知道如何找到多个字符的累积CRC。

我需要在下面找到字符串的累积 CRC,并打印迄今为止每 64 个字符的 CRC。我的答案目前是前 58 个的 bf64,而答案应该是 1a6a。

public class test2 {
static String binaryCRC = "1010000001010011";
static long divisor = Long.parseLong(binaryCRC, 2);
static long cumCRC = divisor;
static long mask = 0x8000;
static long[] crcTable = new long[256];
static int counter = 0;
static String text = "abcdefghijklmnopqrstuvwxyz12345-ABCDEFGHIJKLMNOPQRSTUVWX"
        + "YZ12345abcdefghijklmnopqrstuvwxyz12345-ABCDEFGHIJKLMNOPQ"
        + "RSTUVWXYZ12345abcdefghijklmnopqrstuvwxyz12345-ABCDEFGHIJ"
        + "KLMNOPQRSTUVWXYZ12345abcdefghijklmnopqrstuvwxyz12345-ABC"
        + "DEFGHIJKLMNOPQRSTUVWXYZ12345abcdefghijklmnopqrstuvwxyz12"
        + "345-ABCDEFGHIJKLMNOPQRSTUVWXYZ12345abcdefghijklmnopqrstu"
        + "vwxyz12345-ABCDEFGHIJKLMNOPQRSTUVWXYZ12345.............."
        + "........................................................"
        + "........................................................"
        + "000075dc";
static char[] chars = text.toCharArray();
public static void main(String[] args) {
    for (int i = 0; i < chars.length - 8; i += 2) {
        crc((byte)chars[i], (byte)chars[i + 1]);
        System.out.print(chars[i] + "" + chars[i+1]);
         //Probably wrong
         cumCRC = ((cumCRC >> 8) ^ crcTable[i / 2]) & 0xFFFF;
        if ((i + 2) % 64 == 0) {
            System.out.println(" - " + Long.toHexString(cumCRC));
        }
    }
}
public static void crc(byte first, byte second) {
    long total = ((first << 8) + second);
    //System.out.print(Long.toHexString(total));
    for (int i = 0; i < binaryCRC.length(); i++) {
        if ((total & mask) != 0) {
            total = (total << 1) ^ divisor;
        } else {
            total <<= 1;
        }
    }
    //System.out.println(" -> " + Long.toHexString(total));
    crcTable[counter] = total;
    counter++;
}
}

好的,这更接近了。 您需要检查高位,然后移位,然后是排除 - 或者多项式(如果高位多项式)。 您正在执行之后的移位,这显然是错误的,因为它保证答案始终具有较低的零位。

更新已编辑的答案:

代码现在正确。 但是,您在链接的网站上输入了错误的多项式。 实际多项式也有一个 x16 项。 放进那个领先的。

更新以进行其他编辑:

您不会单独计算每对字节的 CRC。 相反,您继续处理具有更多字节的 CRC。 在第一步之前,您将初始CRC零与两个字节排除或(尽管您可能没有意识到您这样做了)。 只需继续使用中间CRC即可。