Guide
What is a CRC and how to choose its parameters
Understand what a CRC detects, why the CRC-16 name is not enough, and how to choose polynomial, init, reflection, xorout, and byte order.
by Tools in a Tab · Published on · Updated
Short answer
A CRC, or cyclic redundancy check, produces a short value from a sequence of bits. It is used to detect certain accidental errors in frames, files or storage blocks. It does not encrypt data and does not show who created it.
Choosing “CRC-16” does not define a complete algorithm. Two 16-bit models can use different polynomials, initial values, reflection settings or final XORs and produce different results for the same bytes.
The entire model, not just the width
Before implementing or testing a CRC, identify these parameters:
| Parameter | Question it answers |
|---|---|
width |
How many bits are the register and the result? |
poly |
Which generator polynomial is used? |
init |
What value does the register start with? |
refin |
Are the bits of each input byte reflected? |
refout |
Is the register reflected before the final XOR? |
xorout |
What mask is applied when finished? |
check |
What should test vector 123456789 produce? |
You also need to know which bytes the calculation covers and how the result is stored or transmitted in the message. These are protocol rules; naming the CRC does not specify them.
Why “CRC-16” is ambiguous
The ASCII string 123456789 is a common check vector. Two 16-bit models produce:
| Model | Polynomial | init |
refin / refout |
xorout |
Result |
|---|---|---|---|---|---|
| CRC-16/ARC | 0x8005 |
0x0000 |
true / true | 0x0000 |
0xBB3D |
| CRC-16/IBM-3740 | 0x1021 |
0xFFFF |
false / false | 0x0000 |
0x29B1 |
Both results are 16 bits and each is correct for its model. If the documentation only says “CRC-16”, information is still missing.
You can compare these models with the CRC calculator, which shows every parameter of the active preset.
What does the polynomial do?
A CRC interprets the sequence as a binary polynomial and calculates a remainder in
modulo-2 arithmetic. The poly parameter describes the divisor. In the usual
notation, the highest-degree term is omitted because the width determines it.
For example, for 16 bits:
poly 0x1021 → x^16 + x^12 + x^5 + 1
Do not substitute a reflected representation from another implementation for
the normal polynomial representation. 0x8005 and 0xA001 are related by bit
reflection, but they are not interchangeable in an input field: first check
which convention the implementation expects.
Start, reflection and end XOR
init fills the register before processing the first byte. Starting at zero or
all ones can change the result even when the polynomial matches.
refin defines the order in which the bits of each byte enter. refout
describes the register orientation before applying xorout. The reflection of
bits is not the same as reversing the order of the resulting bytes.
xorout applies a mask at the end. Comparing only the inner loops of two
implementations therefore does not establish that they implement the same model.
CRC-32 and CRC-32C are different models
The names can also be confused for 32-bit CRCs:
CRC-32/ISO-HDLC of "123456789" = 0xCBF43926
CRC-32C of "123456789" = 0xE3069283
CRC-32C uses the Castagnoli polynomial and is not an alias of CRC-32/ISO-HDLC. RFC 9260 specifies CRC-32C for SCTP. RFC 1662 documents the 16- and 32-bit frame check sequences (FCS) used in PPP.
Choose parameters from the correct authority
Follow this order:
- Identify the exact version of the protocol, format or device.
- Look for its official specification or manufacturer’s data sheet.
- Copy the canonical name and all parameters, not a shorthand tag.
- Confirm which bytes are included and in what order.
- Check the vector
123456789if the specification provides it. - Verify at least one real frame published by that same authority.
- Document the order of transmission of the result.
A calculator reproduces a specified model. It cannot reliably infer which model incomplete documentation intended.
Example: CRC-16/MODBUS and byte order
Open CRC-16/MODBUS with hexadecimal input.
Enter 02 07 and calculate, or use Load example to reproduce this fixed
test vector. Opening the link does not read or calculate any data.
The hexadecimal bytes 02 07 produce the numeric value 0x1241 with
CRC-16/MODBUS. However, Modbus RTU transmits the least significant byte first:
CRC value: 0x1241
Most significant first: 12 41
Modbus, least significant first: 41 12
Byte order describes how the CRC value is serialized in the frame; it is separate from input-bit reflection. The Modbus Serial Line specification defines both the calculation and this transmission order.
Text and bytes are not the same
The calculator processes bytes. Entering 02 07 in text mode calculates the CRC
of the characters 0, 2, space, 0, 7, not the bytes 0x02 and 0x07.
For text you must also agree on the encoding. The letter é in UTF-8 can
be represented as C3 A9, while a visually equivalent sequence can use
65 CC 81. Different bytes can produce different CRCs, but collisions are
possible: a matching CRC does not prove that the input bytes are identical.
Before comparing results record:
- the exact hexadecimal sequence;
- encoding and normalization, if the source is text;
- whether headers, lengths, addresses or the CRC field itself are included;
- multibyte byte order.
Which errors can a CRC detect?
Detection depends on the polynomial, message length and error pattern. A well-chosen CRC can detect every error of certain types within defined limits, but there is no generic guarantee that applies equally to any polynomial and length.
That is why it is not advisable to invent parameters just because they produce a value of 16 or 32 bits. Use the model studied and required by the system with which you must interoperate.
A CRC does not provide cryptographic security
There is no secret key. Whoever modifies a message can calculate a new CRC, so the receiver cannot distinguish a deliberate alteration from a legitimate message. A CRC neither hides data nor proves the identity of the sender.
For integrity against an attacker an authenticated mechanism is needed, such as a MAC or a signature within an appropriate protocol. A SHA-256 hash is useful for identifying content, but by itself it also does not authenticate the sender.
Interoperability checklist
- Width, polynomial,
init,refin,refoutandxoroutmatch. - The polynomial form uses the convention expected by the implementation.
- Vector
123456789produces the correct check value. - Both sides process exactly the same bytes.
- Text encoding is fixed.
- The result has the correct width, including any leading zeros.
- The order of CRC transmission is documented.
- CRC is used for accidental errors, not for authentication.
The Tools in a Tab calculator processes UTF-8 text or hexadecimal bytes locally. It includes presets and custom parameters from 8 to 64 bits, but the final selection should always come from the specification that governs your system.