Guide
How QR codes work
From a string of text to a printed grid and back again. This is the whole pipeline, with the parts that surprise people flagged as they come up.
A QR code is built by encoding text into bits, adding Reed–Solomon error correction codewords, arranging both in a zigzag through the grid, and applying one of eight mask patterns to avoid problematic visual clusters. Decoding reverses this: locate the finders, correct perspective, read the format bits, unmask, and reconstruct.
Text becomes bits
The encoder first picks a mode based on the content. Numeric mode packs three digits into ten bits. Alphanumeric packs two characters into eleven. Byte mode uses eight bits per byte and handles anything, including UTF-8. The mode matters: the same 40 characters produce a smaller code as digits than as mixed text.
Then it picks the smallest version — the grid size, from version 1 at 21 × 21 modules to version 40 at 177 × 177 — that fits the data at the chosen error correction level. Each version adds four modules per side.
The bitstream gets a mode indicator, a character count, the data itself, a terminator, and padding bytes to fill the capacity exactly. The padding alternates two fixed values, which is why two codes with different short content often look similar in their lower regions.
Reed–Solomon, in plain terms
The data is split into blocks, and each block gets error correction codewords calculated over a finite field — Galois Field 256, the same mathematics used in CDs, DVDs and deep space communication.
The useful property: with n error correction codewords you can repair n/2 corrupted codewords at unknown positions, or n at known positions. Because the decoder can identify unreadable areas, real-world recovery is better than the theory's worst case.
Blocks are then interleaved across the grid, so a coffee stain covering one region damages a little of every block rather than destroying one block entirely. This is why a code can lose a whole corner region and still decode, and why the recovery percentages are meaningful in practice.
Why two codes with the same data can look different
Raw encoded data often produces visual patterns that confuse decoders — large blank areas, or sequences that mimic the finder patterns. So the encoder applies a mask: one of eight fixed patterns XORed across the data region only, leaving the structural elements untouched.
All eight are tried. Each result is scored with penalty rules for runs of same-coloured modules, 2 × 2 blocks, finder-like sequences, and imbalance between dark and light. The lowest-scoring mask wins, and its number is written into the format information so the decoder knows how to reverse it.
This is why encoding the same string with two different libraries can produce visually different codes that both scan perfectly. They picked different masks, and both are valid.
What happens in the camera
- Locate. Scan lines look for the 1:1:3:1:1 dark-light ratio that identifies a finder pattern. Three of them define the code.
- Orient. The three corners give rotation. The missing fourth corner tells the decoder which way is up.
- Correct perspective. Alignment patterns let the decoder undo the keystone distortion of a photo taken at an angle.
- Sample. The timing patterns give module size, and the grid is sampled at module centres.
- Read format bits. These give the error correction level and mask pattern.
- Unmask and de-interleave. Reverse the XOR, reassemble the blocks.
- Correct errors. Reed–Solomon repairs whatever the print, the lighting and the angle damaged.
- Decode. Read the mode indicator and character count, and convert the bits back to text.
On a modern phone this takes a few milliseconds, and it is attempted many times a second until it succeeds. What feels like a slow scan is usually many failed attempts, which points at contrast, focus distance or size — not at the phone.
Frequently asked
Why do two QR codes with the same content look different?
What is the quiet zone for?
How does a QR code work when it is damaged?
Can a QR code be read upside down?
Last reviewed 24 August 2026 · Written and reviewed by the QR Code Builder team