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

4

昨天我问了一个更广泛的问题,但是我决定删除它并把我的问题缩小一些。诚实地说,这是一道作业题。我正在尝试使用以下多项式开发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值。 我目前的答案为bf58,而正确答案应该是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++;
}
}
1个回答

2

好的,这更接近了。您需要检查高位,然后进行移位,如果高位是1,则异或多项式。您之后执行移位,这显然是错误的,因为它保证答案始终具有低位为零。

编辑后的答案更新:

代码现在是正确的。但是,您在链接的网站上输入多项式时输入不正确。实际多项式还有一个x16项。请加入该领先的一项。

另一个编辑的更新:

您不需要单独为每对字节计算CRC。相反,您继续处理更多字节的CRC。在第一步之前,您使用两个字节(尽管您可能没有意识到)将初始CRC和零进行了异或。只需使用中间CRC继续执行此操作即可。


你比我快一点... 这是我的结果,提问者的程序产生了与计算器相同的答案,但向左移位1个比特。 - ajb
如果我的代码正确,那么我的总问题必须在累积CRC上。我有一串字符,并且必须找到它们之间的累积CRC。“...显示与CRC计算或验证相关的每个64个字符行的累积XOR操作的结果。”这基本上意味着算法的32个实例中的累积CRC(每次调用函数时64个字符/ 2个字符)。我该怎么做? - Jerm
很抱歉,您是否愿意提供更详细/具体的信息?我正在尝试理解您所说的内容,但是遇到了困难。 - Jerm
如果我必须这么多地帮助你,那么恐怕我不得不说你的作业失败了。 - Mark Adler
我想是这样。很遗憾在我无法完成它的情况下浪费了这么多时间 - 教科书上关于这个东西的章节毫无价值。 - Jerm
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接