EmbeddedRelated.com

CRC

Category: Standards | Also known as: cyclic redundancy check

A cyclic redundancy check (CRC) is an error-detection scheme that treats a block of data as a polynomial, divides it by a fixed generator polynomial using modulo-2 arithmetic, and appends or compares the remainder (the CRC value) to detect accidental data corruption. CRCs are widely used in communication protocols, storage systems, and firmware integrity checks because they reliably detect burst errors and are efficient to compute in both hardware and software.

In practice

CRCs appear throughout embedded systems wherever data integrity matters: UART/SPI/I2C frame validation, bootloader firmware verification, flash memory integrity checks, and fieldbus protocols such as CAN (CRC-15), Modbus (CRC-16/IBM), and Ethernet (CRC-32/ISO-HDLC). Many MCUs include a dedicated CRC hardware peripheral -- STM32 devices, for example, typically include a CRC unit that computes CRC-32 (the same polynomial as Ethernet) in a single clock cycle per 32-bit word, which is far faster than a software implementation for large buffers.

Choosing the right polynomial matters. Common widths and polynomials include CRC-8/MAXIM (used in 1-Wire), CRC-16/CCITT (used in Xmodem and many wireless stacks), CRC-16/IBM (Modbus, USB), and CRC-32/ISO-HDLC (Ethernet, ZIP, PNG). The polynomial alone does not fully specify behavior: initial value, input/output bit reflection, and final XOR value all affect the result. Two implementations using the same polynomial width but different parameter sets can produce different outputs -- this is why using a fully specified named variant (such as CRC-16/IBM rather than just "CRC-16") is important. The blog post "Practical CRCs for Embedded Systems" covers these parameters in detail.

A common pitfall is mismatching CRC parameters between a transmitter and a receiver -- for example, one side reflecting input bits and the other not -- which produces valid-looking code that silently fails to detect errors. The post "The CRC Wild Goose Chase: PPP Does What?!?!?!" documents exactly this kind of subtle incompatibility in practice. Always validate an implementation against published test vectors for the specific named variant before deploying it.

CRCs detect errors but do not correct them and do not provide any security guarantee; a determined attacker can forge a message that passes a CRC check. For tamper detection or message authentication, use a cryptographic hash or MAC instead. CRC is also not a substitute for a simple additive checksum in all situations: while CRCs catch burst errors and most multi-bit errors very well, they offer only probabilistic protection against random errors, with an undetected error probability of 2^-n for an n-bit CRC against random noise.

Frequently asked

What is the difference between a CRC and a simple checksum?
A simple additive checksum sums data bytes and discards overflow; it generally fails to detect transposed bytes, certain multi-bit errors, and burst errors, though detection can depend on the specific values and checksum width. A CRC uses polynomial division over GF(2), which gives it much stronger algebraic error-detection properties -- a well-chosen n-bit CRC is guaranteed to detect all single-bit errors, all burst errors of length n or less, and most longer bursts. For most communication or storage integrity use cases in embedded systems, a CRC is preferred over a plain checksum.
What does it mean when a CRC implementation is described as 'reflected' or 'bit-reversed'?
Bit reflection reverses the bit order of input bytes, output bytes, or both before processing. Many common CRC variants -- including CRC-32/ISO-HDLC and CRC-16/IBM -- use reflected arithmetic because it simplifies hardware shift-register implementations that process the LSB first. Failing to match the reflection settings between two implementations is one of the most common causes of CRC mismatches. The blog post 'The CRC Wild Goose Chase: PPP Does What?!?!?!' illustrates how this can go wrong in a real protocol.
Should I use the hardware CRC peripheral on my MCU or implement CRC in software?
Hardware CRC peripherals are faster and consume no CPU cycles during computation on devices that support DMA transfers to them, making them a good choice for large payloads or tight timing budgets. The main limitation is that many MCU CRC peripherals support only a fixed set of polynomials or widths -- for example, some STM32 parts default to CRC-32 only, though newer devices offer a programmable polynomial -- so if your protocol requires a different variant such as CRC-16/CCITT, you may still need a software implementation. Software table-driven CRC implementations are compact, portable, and typically fast enough for small frames on any MCU.
How do I verify that my CRC implementation is correct?
Use the published check value for the named CRC variant, which is defined as the CRC of the ASCII string '123456789'. For example, CRC-32/ISO-HDLC should produce 0xCBF43926 for that input. If your implementation matches the check value and all other parameters (init, refin, refout, xorout) align with the specification, it is correct. The blog post 'Practical CRCs for Embedded Systems' lists parameters and check values for commonly used variants.
Can CRC be used for security purposes, such as detecting intentional tampering?
No. CRC is not a cryptographic primitive. Because CRC is a linear function, an attacker who can modify a message can easily compute a new valid CRC for the modified content without knowing any secret. For tamper detection or message authentication, use a cryptographic MAC such as HMAC-SHA256 or AES-CMAC. CRC is appropriate only for detecting accidental, non-adversarial data corruption.

Differentiators vs similar concepts

CRC is often conflated with checksums and cryptographic hashes. A simple additive or XOR checksum is weaker than a CRC -- it misses transposed bytes and many multi-bit errors that a CRC would catch. A cryptographic hash (SHA-256, MD5) or MAC (HMAC, AES-CMAC) is far stronger than a CRC but also much more computationally expensive; it is the right choice when tamper resistance or collision resistance is required. CRC sits in the middle: stronger than a checksum for accidental error detection, but offering no security guarantees against deliberate manipulation.