简体   繁体   English

验证 CRC32 校验和

[英]Validating CRC32 checksum

I am able to successfully generate a CRC32 that matches the expected output.我能够成功生成与预期的 output 匹配的 CRC32。 However, when I try to plug the message M with checksum C (generated by the CRC32 function) back into that same CRC32 generator, I'm not able to get the expected output of 0x00000000.但是,当我尝试将带有校验和 C(由 CRC32 函数生成)的消息 M 插入同一个 CRC32 生成器时,我无法获得预期的 output 0x00000000。

My CRC32 generator is basically just the code here ( https://lxp32.github.io/docs/a-simple-example-crc32-calculation/ ), with an additional function argument for the checksum, since the message and checksum in my case are in separate memory locations upon receipt. My CRC32 generator is basically just the code here ( https://lxp32.github.io/docs/a-simple-example-crc32-calculation/ ), with an additional function argument for the checksum, since the message and checksum in my箱子在收到时位于单独的 memory 位置。

uint32_t crc32(const char* s, size_t n, uint32_t checksum) {
    uint32_t crc = 0xFFFFFFFF;
    size_t i; size_t j;

    for (i = 0; i < n; i++) {
        char ch = s[i];
        uint32_t t = (ch ^ crc) & 0xFF;
        crc = (crc >> 8) ^ crc32_table[t];
    }

    if (i & 1) { // if i ended odd, write a 0x00 pad bit
        uint32_t t = (0x00 ^ crc) & 0xFF;
        crc = (crc >> 8) ^ crc32_table[t];
    }

    // include checksum bits if not 0
    if (checksum) {
        for (j = 0; j < 4; j++) {
            char ch = (checksum & 0xFF);
            uint32_t t = (ch ^ crc) & 0xFF;
            crc = (crc >> 8) ^ crc32_table[t];
            checksum >>= 8;
        }
    }
    else {
        // append 32-bits of 0's
        for (j = 0; j < 4; j++) {
            uint32_t t = (0x00 ^ crc) & 0xFF;
            crc = (crc >> 8) ^ crc32_table[t];
        }
    }
    return ~crc;
}

bool validate_crc32(const char* msg, size_t n, uint32_t checksum) {
    uint32_t res = crc32(msg, n, checksum);
    return res == 0;
}

CRC32 Input 1: 0x61 0x62 0x63 0x64 0x00 0x00 0x00 0x00 CRC32 输入 1:0x61 0x62 0x63 0x64 0x00 0x00 0x00 0x00

CRC32 Output 1: 0x 87988EF9 CRC32 Output 1:0x 87988EF9

CRC32 Input 2: 0x61 0x62 0x63 0x64 0x87 0x98 0x8E 0xF9 CRC32 输入 2:0x61 0x62 0x63 0x64 0x87 0x98 0x8E 0xF9

CRC32 Output 2: 0x5D19F7CF CRC32 Output 2:0x5D19F7CF

I feel like I'm not understanding something right here...我觉得我在这里没有理解一些东西......

  1. When you do it right, you won't get zero.如果你做对了,你就不会得到零。 You get the same constant every time, but it isn't zero for this CRC.你每次都得到相同的常数,但这个 CRC 不为零。 For this one, the constant is 0x2144df1c .对于这个,常数是0x2144df1c (It's not zero because there is a final exclusive-or with a non-zero value.) (它不是零,因为有一个非零值的最终异或。)
  2. You're not doing it right.你做的不对。 First, you do not need to and should not append four zeros.首先,您不需要也不应该 append 四个零。 Just calculate the CRC of the message.只需计算消息的CRC。 Second, append the CRC in little -endian order.其次,append CRC 的端序。 Not big-endian order.不是大端顺序。 (Because this is a reflected CRC that shifts down.) (因为这是一个向下移动的反射 CRC。)
  3. There is little point in checking the CRC this way.以这种方式检查 CRC 没有什么意义。 Just compute the CRC on the message, and then compare the result of that to the CRC that was sent.只需计算消息的 CRC,然后其结果与发送的 CRC 进行比较。 That is far easier, more transparent to someone reading your code, and avoids an unnecessary calculation of the CRC on four more bytes.这对于阅读您的代码的人来说更容易、更透明,并且避免了在另外四个字节上不必要地计算 CRC。 The compare is much faster than a CRC calculation on four bytes.比较比对四个字节的 CRC 计算快得多。
  4. Why are you sticking an extra zero in there for odd-length messages?为什么要在奇数长度的消息中添加一个额外的零?

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

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