简体   繁体   English

我的CRC算法出了什么问题? (JAVA)

[英]What's wrong with my CRC algorithm? (Java)

Had asked a much broader question yesterday, but figured it may be prudent to delete it and narrow my question down a bit. 昨天曾问过一个更广泛的问题,但认为删除它并稍微缩小我的问题可能是谨慎的。 Again, in the interest of honesty, yes, this is homework. 同样,为了诚实,是的,这是家庭作业。 I'm trying to develop a CRC algorithm with the following polynomial: 我正在尝试使用以下多项式开发CRC算法:

x15+x13+x6+x4+x1+1 X15 + X13 + 5233 + X4 + X1 + 1

I'm supposed to pass two bytes (8-bits), combine them into a 16-bit result (so I shift the first byte left 8, then add the two together), and then find the CRC using the above polynomial. 我应该传递两个字节(8位),将它们组合成一个16位结果(所以我将第一个字节左移8,然后将两个加在一起),然后使用上面的多项式找到CRC。 I've been checking what my output should be using this tool , but I can't seem to get the correct answer. 我一直在检查我的输出应该使用这个工具 ,但我似乎无法得到正确的答案。

What I have: 是)我有的:

(Relevant Global Variables) (相关的全球变量)

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

(Actual Algorithm) (实际算法)

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

EDIT: My attempt to revise my for-loop utilizing the suggestion given below: 编辑:我尝试使用下面给出的建议修改我的for循环:

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

Perhaps I'm doing it incorrectly, but my output becomes incredibly far off when I do this way. 也许我做错了,但是当我这样做时,我的输出变得非常遥远。 When setting the value of my two bytes to the ASCII values of chars 'a' and 'b' (total = 6162), I get 6162 -> 4f1b065d, when I should be getting 77eb. 当我将两个字节的值设置为字符'a'和'b'(总计= 6162)的ASCII值时,我得到6162 - > 4f1b065d,当我得到77eb时。

EDIT 2: I briefly outlined it below, but in the interest of clarity, I'm adding the rest of what I need to do, because I don't know how to find the cumulative CRC across multiple characters. 编辑2:我在下面简要概述了它,但为了清楚起见,我正在添加我需要做的其余部分,因为我不知道如何在多个字符中找到累积CRC。

I need to find the cumulative CRC of the String below, and print the CRC thus far every 64th character. 我需要找到下面字符串的累积CRC,并且每隔64个字符打印一次CRC。 My answer is currently bf58 for the first 64, when the answer SHOULD be 1a6a. 我的答案目前是前64位的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++;
}
}

Ok, this is closer. 好的,这更接近了。 You need to check the high bit, then shift, then exclusive-or the polynomial if the high bit was a one. 你需要检查的高位,再移位,然后异或多项式,如果高位一个。 You are doing the shift after, which is obviously wrong since it guarantees that the answer always has a low bit of zero. 你之后正在进行转换,这显然是错误的,因为它保证了答案始终具有零位的低位。

Update for edited answer: 已编辑答案的更新:

The code is now correct. 代码现在是正确的。 However you are entering the polynomial incorrectly on the website you linked. 但是,您在链接的网站上输入的多项式不正确。 The actual polynomial has an x 16 term as well. 实际多项式也具有x 16项。 Put in that leading one. 投入那个领先的。

Update for another edit: 更新另一个编辑:

You do not calculate a CRC for each pair of bytes separately. 您不分别为每对字节计算CRC。 Instead you continue to process the CRC with more bytes. 相反,您继续使用更多字节处理CRC。 Before the first step, you exclusive-ored the initial CRC, zero, with the two bytes (though you may not realize you did that). 在第一步之前,您使用两个字节对初始CRC(零)进行独占(尽管您可能没有意识到这样做了)。 Just keep doing that with the intermediate CRCs. 只需继续使用中间CRC。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM