CRC (Cyclic Redundancy Check) is an error-detection algorithm that’s everywhere - from network packets to file systems to embedded systems.

If you’ve ever wondered how your computer knows when a file is corrupted or how network protocols detect transmission errors, CRCs are often the answer.

What problem do CRCs solve?

Data corruption can happen from:

  • Network transmission - electromagnetic interference, faulty hardware
  • Storage media - bit flips, failing drives
  • Serial communication - noise on long cables, timing issues

CRC gives us a fast way to detect if data has been corrupted. It’s not about security (use cryptographic hashes for that) - it’s about reliability.

How CRCs actually work

The math (simplified)

CRC treats your data as a giant binary number and divides it by a special polynomial. The remainder becomes your checksum.

Data:       11010011101100  (your message)
Polynomial: 1011            (CRC divisor)
            _______________
Polynomial ) Data

Remainder = CRC checksum

The interesting part: this division is done using XOR operations instead of regular arithmetic, making it really fast in hardware.

Basic concept

When you send data:

  1. Calculate CRC checksum from your data
  2. Send data + checksum
  3. Receiver calculates CRC on received data
  4. If checksums match, data is likely good

Where you’ll find CRCs

Network protocols

  • Ethernet - CRC-32 on every frame
  • CAN bus - CRC-15 for automotive networks
  • USB - CRC-5 for tokens, CRC-16 for data

File formats

  • ZIP files - CRC-32 for each compressed file
  • PNG images - CRC-32 for each chunk
  • GZIP - CRC-32 for compressed data

Embedded systems

// Common pattern in firmware
typedef struct {
    uint32_t config_version;
    uint16_t sensor_threshold;
    uint8_t  device_id;
    uint32_t crc32;  // CRC of everything above
} config_t;

Real-world usage patterns

Common uses I’ve seen

  • Network packets: Each packet includes a CRC to detect transmission errors
  • Configuration storage: Embedded systems store settings with CRC to detect corruption on boot
  • File transfers: Many protocols add CRC to chunks to verify integrity
  • Sensor data: Add CRC to readings before transmitting over noisy channels

Common CRC variants

Different applications use different polynomials optimized for their use case:

CRC TypePolynomialUse Case
CRC-80x071-Wire bus, sensors
CRC-16-CCITT0x1021Bluetooth, SD cards
CRC-320x04C11DB7Ethernet, ZIP, PNG
CRC-32C0x1EDC6F41iSCSI, Btrfs, ext4

Limitations to know about

Not cryptographically secure

CRCs are trivial to forge - anyone can modify data and calculate a valid CRC. Never use CRC for security.

Collision possibility

Different data can produce the same CRC (though it’s rare with good polynomials).

Can’t correct errors

CRC only detects errors - you’ll need something like Reed-Solomon codes if you want to fix them.

Specific error patterns can slip through

Carefully crafted errors that are multiples of the polynomial won’t be detected.

Things I’ve learned

  1. Use hardware CRC when available - many MCUs have CRC peripherals that are way faster
  2. Pick the right polynomial - don’t just use CRC-32 everywhere; smaller CRCs are fine for small data
  3. Include length in CRC calculation - helps catch truncation errors
  4. For critical systems - consider using multiple error detection methods (CRC + checksum + sequence numbers)

CRCs are one of those things that just quietly do their job in the background. They’re pretty much everywhere once you start looking for them.