6

I'm learning about CRCs, and search engines and SO turn up nothing on this....

Why do we have "Normal" and "Reversed" and "Reciprocal" Polynomials? Does one favor Big Endian, Little Endian, or something else?

someprogrammer
  • 229
  • 2
  • 13

1 Answers1

9

The classic definition of a CRC would use a non-reflected polynomial, which shifts the CRC left. If the word size being used for the calculation is larger than the CRC, then you would need an operation at the end to clear the high bits that were shifted into (e.g. & 0xffff for a 16-bit CRC).

You can flip the whole thing, use a reflected polynomial, and shift right instead of left. That gives the same CRC properties, but the bits from the message are effectively operated on from least to most significant bit, instead of most to least significant bit. Since you are shifting right, the extraneous bits get dropped off the bottom into oblivion, and there is no need for the additional operation. This may have been one of the early motivations to use a very slightly faster and more compact implementation.

Sometimes the specification from the original hardware is that the bits are processed from least to most significant, so then you have to use the reflected version.

No, none of this favors little or big endian. Either kind of CRC can be computed just as easily in little-endian or big-endian architectures.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • So how do you reverse it? If I have 0x04C11DB7 polynomial how do I reverse it into 0xEDB88320? (this one is simple to find on wikipedia or in zlib source but if I wanted to reverse 0x404098E2 for that matter what should I do? – tansy Jun 09 '20 at 12:28
  • 2
    Just write it in binary and reverse the 32 bits. `00000100110000010001110110110111` which reversed is `11101101101110001000001100100000`, equal to `0xedb88320`. – Mark Adler Jun 09 '20 at 21:02
  • 1
    By the way, your `0x404098E2` can't be a CRC polynomial. The polynomial must have a `1` term, i.e., the numeric representation must be odd. It can't be even. – Mark Adler Jun 09 '20 at 21:03
  • Thanks, I get that. How do I do that in C? Speaking of 0x404098E2 polynomial, I found it [here](https://guru.multimedia.cx/misusing-crcs-for-error-correction/) amongst the others, and wanted to check but didn't know exactly what that reverse mean till I come here. It might be a typo as well. Anyway, I wanted to check them to get why would CRC32C be better than CRC32/B cause I don't see that. – tansy Jun 09 '20 at 22:08
  • Since it's even, the result ends up being a 31-bit CRC. It's not a 32-bit CRC. – Mark Adler Jun 09 '20 at 23:55
  • [This paper](https://users.ece.cmu.edu/~koopman/networks/dsn02/dsn02_koopman.pdf) shows the results of various metrics of the goodness of several 32-bit CRCs. – Mark Adler Jun 10 '20 at 00:12
  • I'm guessing your "CRC32C" uses the Castagnoli polynomial. I don't know what "CRC32/B" is. – Mark Adler Jun 10 '20 at 00:16
  • No one ever needs to do that reversal in C, since either `0x04C11DB7` or `0xEDB88320` is entered as a constant in the C code depending on the bit ordering of the CRC. In any case, reversing the bits in C is quite simple, using the &, |, >>, and << operations. – Mark Adler Jun 10 '20 at 00:18
  • I've seen several times CRC #0x04C11DB7 being referred as **b**, \[[1](https://md5calc.com/hash/crc32b/)\], \[[2](https://hash.online-convert.com/crc32b-generator)\], \[[3](https://crc32b.cryptohash.net/)\], and [many more](https://duckduckgo.com/?q=crc32b&t=ffab). When I tried to learn anything about that that was confusing, but I can't help it's been called this way. – tansy Jun 10 '20 at 05:53
  • Ok, I think I tracked down that name. It originated with [PHP](https://www.php.net/manual/en/function.hash-algos.php), where it seems someone there made it up, to distinguish it from the thing they call crc32. No one else calls it CRC-32B, except as influenced by the PHP name. That CRC can be called many things: CRC-32/ISO-HDLC, CRC-32, CRC-32/ADCCP, CRC-32/V-42, CRC-32/XZ, PKZIP CRC. However CRC-32B is not a correct name. – Mark Adler Jun 10 '20 at 18:33