CRC Calculator

What Is CRC32?

CRC32 is a 32-bit checksum that tells you whether a block of data has been changed by accident. The sender computes four bytes from the data and attaches them; the receiver repeats the computation and compares. If the two values differ, the data was corrupted on the way.

It is the check behind Ethernet frames, ZIP and gzip archives, PNG images and countless device protocols — chosen because it is tiny, very fast, and extremely good at catching the kinds of errors that hardware actually produces. To compute one right now, use the CRC32 calculator.

The idea: a remainder after division

A simple checksum adds all the bytes together. That misses a lot: swap two bytes and the sum is unchanged. A CRC instead treats the whole message as one enormous binary number, divides it by a fixed constant — the generator polynomial — and keeps the remainder. Changing any bit changes the remainder in a way that depends on where the bit is, so reordered or shifted data is detected too.

The division is not ordinary arithmetic. It is done without carries, which means subtraction becomes XOR. That is what makes a CRC cheap in hardware: a shift register and a few XOR gates.

A worked example with a 3-bit CRC

The mechanics are identical at any width, so here is a small one. Message 1101, generator 1011 (a 3-bit CRC). Append three zero bits to the message, then repeatedly XOR the generator under the leftmost 1:

  1101000      message with 3 zeros appended
^ 1011
  -------
  0110000
^  1011
  -------
  0011100
^   1011
  -------
  0001010
^    1011
  -------
  0000001      remainder = 001

The CRC is 001 and the transmitted message is 1101001. The receiver divides those seven bits by the same generator; a remainder of zero means no error was detected. CRC32 does exactly this with a 33-bit generator and a 32-bit remainder.

The CRC32 parameters

The standard CRC-32 is defined by these values:

Polynomial0x04C11DB7 (reflected: 0xEDB88320)
Initial value0xFFFFFFFF
Input reflectedYes — bytes are processed least-significant bit first
Output reflectedYes
Final XOR0xFFFFFFFF
Check valueCRC32 of 123456789 is 0xCBF43926

Written out, the polynomial is:

x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

The extra steps around the plain division each solve a problem:

CRC32 in code

The direct bit-by-bit version follows the definition:

uint32_t crc32(const uint8_t *data, size_t len)
{
    uint32_t crc = 0xFFFFFFFF;
    while (len--) {
        crc ^= *data++;
        for (int i = 0; i < 8; i++)
            crc = (crc & 1) ? (crc >> 1) ^ 0xEDB88320 : crc >> 1;
    }
    return crc ^ 0xFFFFFFFF;
}

The inner loop depends only on the low byte of the register, so its result can be precomputed for all 256 byte values. That gives the table-driven version used almost everywhere, about eight times faster:

static uint32_t table[256];

void crc32_init(void)
{
    for (uint32_t i = 0; i < 256; i++) {
        uint32_t c = i;
        for (int k = 0; k < 8; k++)
            c = (c & 1) ? (c >> 1) ^ 0xEDB88320 : c >> 1;
        table[i] = c;
    }
}

uint32_t crc32(const uint8_t *data, size_t len)
{
    uint32_t crc = 0xFFFFFFFF;
    while (len--)
        crc = table[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
    return crc ^ 0xFFFFFFFF;
}

In practice you rarely write it yourself. Most languages ship the standard CRC-32:

LanguageCall
Pythonzlib.crc32(b"hello")
Node.js 22+require("node:zlib").crc32("hello")
PHPcrc32("hello") or hash("crc32b", "hello")
Gocrc32.ChecksumIEEE([]byte("hello"))
Javajava.util.zip.CRC32
C# / .NETSystem.IO.Hashing.Crc32
C (zlib)crc32(0L, buf, len)

Every one of these returns 0x3610A686 for hello. One trap: PHP's hash("crc32", …) without the b is the bzip2 variant and returns a different value.

What CRC32 detects — and what it does not

CRC32 is guaranteed to detect:

For any other random corruption, the chance of it slipping through is 1 in 232, about 1 in 4.3 billion.

What it does not give you:

CRC32 compared with other checksums

AlgorithmSizeSpeedUse it for
CRC-1616 bitsVery fastShort frames on serial buses (Modbus, CAN, USB)
CRC-3232 bitsVery fastFiles, archives, network frames
CRC-32C32 bitsFastest (CPU instruction)Storage systems, new protocol designs
CRC-6464 bitsVery fastVery large objects where 32 bits is too few
MD5128 bitsFastLegacy checks only — cryptographically broken
SHA-256256 bitsSlowerAnything where tampering matters

For shorter checksums see the CRC16 calculator and the Modbus CRC calculator. To check a download, the file checksum calculator computes CRC32 and SHA-256 together.

CRC32 is often confused with its sibling CRC32C; the differences are laid out in CRC32 vs CRC32C. For checksums that are not CRCs at all — sums, XOR, Fletcher, Adler — use the checksum calculator, and for the 8-bit and 64-bit families the CRC8 calculator and CRC64 calculator.

Frequently asked questions

What does CRC32 stand for?

Cyclic Redundancy Check, 32 bits. "Cyclic" refers to the cyclic codes the method is based on, "redundancy" to the extra bits added to the data, and "check" to their purpose: detecting errors.

Is CRC32 a hash function?

It is a checksum, and it can be used as a fast non-cryptographic hash, but it is not a cryptographic hash. It has no resistance to deliberate collisions, and its output is only 32 bits, so two different inputs share a CRC32 once you have roughly 77,000 of them with 50% probability.

Can a CRC32 be reversed to get the original data?

No — infinitely many inputs share every CRC32 value, so the original data cannot be recovered. What is possible is the opposite problem: constructing some input, or patching four bytes of an existing one, so that it has a chosen CRC32. That is why CRC32 must not be used for security.

What is the difference between CRC32 and CRC32C?

Only the polynomial. CRC-32 uses 0x04C11DB7; CRC-32C (Castagnoli) uses 0x1EDC6F41, which detects more error patterns in typical packet sizes and has dedicated CPU instructions on x86 (SSE4.2) and ARMv8. The two give completely different results and are not interchangeable.

How fast is CRC32?

A simple table-driven implementation processes roughly 400–600 MB/s per core. Slicing-by-8 reaches a few GB/s, and implementations using carry-less multiplication instructions exceed 10 GB/s — far faster than any cryptographic hash.