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:
- Calculate CRC checksum from your data
- Send data + checksum
- Receiver calculates CRC on received data
- 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 Type | Polynomial | Use Case |
|---|---|---|
| CRC-8 | 0x07 | 1-Wire bus, sensors |
| CRC-16-CCITT | 0x1021 | Bluetooth, SD cards |
| CRC-32 | 0x04C11DB7 | Ethernet, ZIP, PNG |
| CRC-32C | 0x1EDC6F41 | iSCSI, 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
- Use hardware CRC when available - many MCUs have CRC peripherals that are way faster
- Pick the right polynomial - don’t just use CRC-32 everywhere; smaller CRCs are fine for small data
- Include length in CRC calculation - helps catch truncation errors
- 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.