Skip to content
UseQR
ESC

↑↓ MOVE↵ OPEN48 PLACES

Spec & internals

QR code checksum and integrity

A QR code carries no payload checksum. Reed–Solomon protects codewords against damage, and BCH codes protect the 15-bit format and 18-bit version fields, but a code that decodes cleanly proves nothing about who made it. Integrity and authenticity must live in the payload — a CRC, a token or a signature.

View as MarkdownPaste this page into any AI assistant — it is plain, portable Markdown.

What protection a QR code actually contains

Three error-control mechanisms exist in the symbol, protecting three different things:

Mechanism Protects Size
Reed–Solomon data + EC codewords 7–30% of codewords, by level
BCH (15,5) format information — EC level and mask 10 check bits on 5 data bits, stored twice
BCH (18,6) version information (versions 7+) 12 check bits on 6 data bits, stored twice

Notice what is missing: there is no checksum, CRC or hash over the payload itself. The bit stream is mode indicators, character counts, data and padding — nothing that summarises or fingerprints the content. QR's error control exists to survive transport damage (dirt, blur, missing modules), not to vouch for the data.

What Reed–Solomon does and does not guarantee

What it does: if the damaged codewords are within the level's budget, the decoder recovers the original codewords exactly — error correction is reconstruction, not approximation. As a side effect it provides strong error detection: random corruption beyond the correctable budget almost always fails to decode rather than producing wrong text, because a fabricated-but-consistent codeword set is astronomically unlikely to arise by accident. Silent misdecodes are possible in principle when damage grossly exceeds the budget, which is one reason critical systems re-verify decoded content rather than trusting a lone scan.

What it does not do:

  • Authenticate. Reed–Solomon math is public and runs in every generator. Anyone can produce a flawlessly valid QR code saying anything — that is precisely what a quishing sticker is. "It scanned cleanly" carries zero evidence about who created it.
  • Validate meaning. A decoder happily returns a malformed URL, a wrong account number or an expired link. Correct transport of wrong content is still wrong content.
  • Protect the payload's semantics. A typo in the URL you encoded is preserved with perfect fidelity.

If you need integrity, put it in the payload

Since the symbol layer will not carry it, the payload layer must. Three escalating patterns, all in production use:

  1. Checksums for typos and truncation. EMVCo payment payloads — the format behind PIX — end in a mandatory CRC-16 over the whole string, so a mis-scanned or hand-mangled payload fails validation in the payment app (details: PIX CRC16 checksum). Same idea: check digits in GS1 GTINs.
  2. Server-side validation for guessing resistance. Ticketing and voucher codes embed a random token that the backend validates — no offline forgery value, revocable, but requires connectivity.
  3. Signatures for authenticity. A cryptographic signature over the payload proves origin offline — anyone can verify with the public key, only the key holder can issue. Formats and trade-offs: signed QR codes and authenticity.

The pattern to internalise: the QR layer is a transport; trust decisions belong to the content. Scanner-side, the same logic applies to humans — check what a code decodes to before acting on it.

Generator-side, the useful integrity check is the round trip: render the code, decode it, compare against the intended payload byte for byte. That is exactly what /validate automates, and what UseQR's /api/v1/verify endpoint exposes for pipelines.

FAQ

Does a QR code have a built-in checksum?

Not over the payload. Reed–Solomon codewords protect against physical damage and BCH codes protect the small format and version fields, but nothing in the symbol fingerprints or validates the data content itself.

Can a QR code decode to the wrong text?

Physically corrupted codes overwhelmingly fail to decode rather than misdecode, because consistent-but-wrong codeword sets rarely occur by chance. The realistic risk is different — a perfectly valid code that was malicious or mistyped from the start.

How do payment QR codes prevent errors?

The payload format adds its own protection. EMVCo-derived formats such as PIX end with a mandatory CRC-16 the payment app must verify, and account identifiers often carry check digits, so mangled payloads are rejected before money moves.

How do I make a QR code tamper-evident?

You cannot at the symbol level — anyone can print a valid code. Embed a server-validated token or a cryptographic signature in the payload, or control the physical medium with tamper-evident labels, and verify scans against the issuing system.

Try it — free, no signup