CRC32 vs CRC32C
CRC32 and CRC32C are both 32-bit cyclic redundancy checks with the same structure and the same cost. They differ in exactly one parameter — the generator polynomial — and that is enough to make their results completely unrelated.
If a checksum will not verify and both sides swear they use "CRC32", this is the first thing to rule out. Paste your data into the CRC32 calculator: its table lists the result for both variants side by side.
The parameters side by side
| CRC32 | CRC32C | |
|---|---|---|
| Also called | CRC-32/ISO-HDLC, IEEE 802.3, PKZIP | CRC-32/ISCSI, Castagnoli |
| Polynomial | 0x04C11DB7 | 0x1EDC6F41 |
| Polynomial, reflected | 0xEDB88320 | 0x82F63B78 |
| Initial value | 0xFFFFFFFF | 0xFFFFFFFF |
| Input / output reflected | yes / yes | yes / yes |
| Final XOR | 0xFFFFFFFF | 0xFFFFFFFF |
CRC of 123456789 | 0xCBF43926 | 0xE3069283 |
CRC of hello | 0x3610A686 | 0x9A71BB4C |
To tell which one a piece of code implements, search it for the constant: EDB88320 or 04C11DB7 means CRC32, 82F63B78 or 1EDC6F41 means CRC32C.
Where each one is used
| CRC32 | CRC32C |
|---|---|
| Ethernet frames | iSCSI, SCTP |
| ZIP, gzip, zlib | ext4 metadata, Btrfs |
| PNG chunks | LevelDB, RocksDB, Snappy framing |
| SATA, MPEG-2 (a variant) | Apache Kafka record batches |
crc32() in Python, PHP, Java, Go | Google Cloud Storage object checksums |
The pattern: formats designed before the mid-2000s use CRC32, because that was the polynomial everybody already had. Storage and networking systems designed since then mostly chose CRC32C.
Why CRC32C exists
Better error detection at common sizes
All 32-bit CRCs catch every burst error up to 32 bits and miss about 1 in 4.3 billion random corruptions. Where polynomials differ is in how many scattered bit flips they are guaranteed to catch at a given message length. According to Philip Koopman's published tables, the Castagnoli polynomial detects every error of up to five flipped bits in messages up to about 5,200 bits, while the IEEE polynomial keeps that guarantee only up to a few hundred bits. For packet-sized data, CRC32C is the stronger check.
Hardware support
Intel added a crc32 instruction with SSE4.2 in 2008, and it implements the Castagnoli polynomial only. That made CRC32C far cheaper than a table lookup on servers, which is why storage software adopted it. ARMv8 provides instructions for both polynomials. CRC32 on x86 can be accelerated too, using carry-less multiplication, but it takes considerably more code.
Computing each in code
| Language | CRC32 | CRC32C |
|---|---|---|
| Python | zlib.crc32(data) | crc32c or google-crc32c package |
| Go | crc32.ChecksumIEEE(data) | crc32.Checksum(data, crc32.MakeTable(crc32.Castagnoli)) |
| Java | java.util.zip.CRC32 | java.util.zip.CRC32C (Java 9+) |
| C (x86) | zlib crc32() | _mm_crc32_u8 / _mm_crc32_u64 |
A portable bit-by-bit version differs between the two by one constant:
uint32_t crc32_generic(const uint8_t *data, size_t len, uint32_t poly)
{
uint32_t crc = 0xFFFFFFFF;
while (len--) {
crc ^= *data++;
for (int i = 0; i < 8; i++)
crc = (crc & 1) ? (crc >> 1) ^ poly : crc >> 1;
}
return crc ^ 0xFFFFFFFF;
}
/* CRC32: crc32_generic(buf, n, 0xEDB88320) */
/* CRC32C: crc32_generic(buf, n, 0x82F63B78) */Which should you choose?
- Reading or writing an existing format: you have no choice — use what the format specifies.
- Designing something new: prefer CRC32C. It detects more, and it is hardware-accelerated on every current server and phone CPU.
- Maximum portability with no dependencies: CRC32 is in the standard library of nearly every language.
- Protection against tampering: neither. Use SHA-256.
For background on how the computation works, see What is CRC32?. For larger data where 32 bits is not enough, see the CRC64 calculator; to hash a file with both CRC32 and CRC32C at once, use the file checksum calculator.
Frequently asked questions
Are CRC32 and CRC32C compatible?
No. They use different polynomials, so the same input gives unrelated results: for "123456789", CRC32 is 0xCBF43926 and CRC32C is 0xE3069283. A checksum written with one cannot be verified with the other.
Is CRC32C faster than CRC32?
On x86 it usually is, because SSE4.2 has a dedicated instruction that computes CRC32C and nothing else. Modern CRC32 implementations close most of the gap with carry-less multiplication, and ARMv8 has instructions for both. Without hardware support the two are exactly the same speed.
Which one does ZIP use? And ext4?
ZIP, gzip and PNG use CRC32. ext4 metadata checksums, Btrfs, iSCSI and SCTP use CRC32C.
Can I convert a CRC32 into a CRC32C?
No. There is no way to derive one from the other without the original data. You have to recompute the checksum over the bytes.
What does the "C" in CRC32C stand for?
Castagnoli, after Guy Castagnoli, who published the polynomial 0x1EDC6F41 in 1993 in a study of 32-bit CRC polynomials with better error-detection properties than the IEEE one.