Skip to main content
CRC Calc

CRC mismatch troubleshooting checklist

Work through Width, Poly, Init, RefIn/RefOut, XorOut, input encoding, and byte order in order to find why two calculators disagree.

6 min readVerification
01

Start with the standard check value

CRC results depend on more than the polynomial. Width, initial value, input reflection, output reflection, final XOR, input encoding, and byte order must all match — a difference in any one of these can produce a different checksum even when both tools are, in every other respect, computing correctly. Before comparing implementations line by line, run the standard ASCII test string 123456789 through each one and compare the result to that model's own published check value, not directly to each other.

If both tools agree with their respective model's published check value but still disagree with each other on real input, they are not implementing the same CRC model at all — no amount of parameter tweaking will make two different models agree, and the fix is to identify which model the protocol or file format actually specifies. If neither tool matches its own published check value, the bug lives inside that implementation, and the checklist below narrows down where.

02

The seven-point checklist, in order

Work through the parameters below in this order. Each one can independently make two otherwise-identical calculators disagree, and checking from the most structural (width) to the most easily overlooked (byte order) rules out the fastest, most common causes first.

  • Width — Confirm both implementations use the same register width (8, 16, 32, or 64 bits). A width mismatch changes every downstream step, including how Init and XorOut are masked.
  • Polynomial (Poly) — Confirm the exact hex value, and confirm it is written in the same notation (normal vs reflected) your engine expects. 0x1021 and its bit-reversed form 0x8408 are the same polynomial written two different ways, not two different polynomials.
  • Initial value (Init) — Confirm the register's starting value. Many models default to an all-zero register, but several widely used ones — including CRC-16/MODBUS and CRC-16/IBM-3740 — start from an all-ones register, which changes the result even when the input and every other parameter match.
  • Input/output reflection (RefIn / RefOut) — Confirm whether each input byte is processed least-significant-bit first (RefIn) and whether the final register is bit-reversed relative to the model definition (RefOut). These two flags are set independently; a model can reflect one without the other.
  • Final XOR (XorOut) — Confirm the value XORed into the register after processing and after reflection is resolved. Two models can share every other parameter and differ only in XorOut — CRC-16/ARC and CRC-16/MAXIM-DOW are exactly this case.
  • Input encoding — Confirm both tools are hashing the same bytes. The text "123" typed into an ASCII field is bytes 0x31 0x32 0x33; the same three characters typed into a hex-input field are the single byte 0x12. Mixing up a text field and a hex field is one of the most common sources of a mismatch that looks like a parameter bug but isn't.
  • Byte order — Confirm you are comparing the numeric CRC result, not its serialized bytes on the wire. A calculator may report CRC-16 value 0x4B37; Modbus RTU transmits that as bytes 0x37 0x4B (low byte first), while CRC-32/ISO-HDLC in an Ethernet trailer is conventionally shown high byte first. The CRC model defines the number; the protocol defines how it is serialized.
03

Two checks people skip

Reflection is the parameter most often implemented backward, because RefIn and RefOut look symmetric but are not necessarily applied the same way inside a given engine. A frequent bug is reflecting each input byte, using a reflected polynomial with a right-shifting register — which already accounts for RefIn — and then reflecting the final output again without checking whether the engine's convention already produced the correct orientation. The result is a value that is wrong in a way that looks like a sign or byte-order bug rather than a double reflection.

Input encoding rarely produces an error message — a text field and a hex field both accept the same-looking characters and both happily produce a checksum, so a wrong choice fails silently. Before comparing two implementations, print or log the exact byte sequence each one is about to feed into the CRC. If those bytes differ, the CRC engines themselves are irrelevant; fix the input first.

Reference bytesPlain text
"123" as ASCII text        -> 31 32 33  (3 bytes)
"123" as a hex-string field -> 12        (1 byte)
04

A repeatable workflow to isolate the difference

First, confirm the byte sequence each tool is hashing is identical — log it if the tool allows it. Second, run the ASCII string 123456789 through both and compare each result to that model's published check value rather than to each other; a mismatch here means the models themselves differ, not the input. Third, if both match their own check values but the real input still disagrees, work down the checklist above one parameter at a time against the algorithm's published Width, Poly, Init, RefIn, RefOut, and XorOut, rather than guessing which one is wrong.

If sample input/output pairs are available but the model name is not confirmed, the CRC identifier tool recalculates a data-and-checksum pair against every catalog model and reports every one that reproduces it — a faster way to find which model is actually in play than testing checklist items against a guess. When a message and its CRC field both need validating together rather than compared separately, the residue check described in the CRC residue guide validates the complete codeword in a single pass.

Apply this reference

Change CRC parameters and compare standard algorithm results using the browser-based calculator.