ENES
qr-codeEngineering Guide

How QR Codes Work: Encoding Modes and Error Correction Levels (2026)

AS
Published on 2026-10-19ยท8 min readยทDaily Toolbox Engineering

How QR Codes Work: Encoding Modes and Error Correction Levels

A QR code looks like random noise, but it's one of the most carefully engineered data formats in everyday life: a 2D barcode that survives torn posters, coffee stains, and phone cameras held at angles โ€” while packing thousands of characters into a square inch. The secret is a layered design: efficient encoding modes for different data types, wrapped in Reed-Solomon error correction that can reconstruct up to 30% of destroyed data.

Structure: More Than Black Squares

A QR symbol has fixed anatomical features (defined in ISO/IEC 18004):

  • Finder patterns โ€” the three large squares in the corners. Scanners locate them first; their 1:1:3:1:1 black-white ratio is detectable at any rotation or scale, which is why QR codes scan upside-down.
  • Alignment patterns โ€” smaller squares that let the scanner correct for perspective distortion (a code photographed at an angle).
  • Timing patterns โ€” alternating black/white modules between finders that establish the grid's row/column coordinates.
  • Format information โ€” 15 bits near the finders encoding the error correction level and the mask pattern used (more below).
  • Version information โ€” on larger codes (version 7+), extra bits naming the symbol size.

Everything else is data modules plus error-correction modules, in a grid whose size depends on the version: version 1 is 21ร—21 modules; each version adds 4 modules per side, up to version 40 at 177ร—177.

Encoding Modes: Packing Data Efficiently

Raw bytes would waste space, so QR defines modes that pack common data types tighter:

Mode Indicator What it encodes Density
Numeric 0001 Digits 0โ€“9 ~3โ…“ bits per digit (10 bits per 3 digits)
Alphanumeric 0010 0โ€“9, Aโ€“Z (upper only), space, $%*+-./: 5.5 bits per char (11 bits per 2 chars)
Byte 0100 Any bytes (ISO-8859-1, or UTF-8 via ECI) 8 bits per byte
Kanji 1000 Shift-JIS kanji 13 bits per character

The bit stream starts with the 4-bit mode indicator, then a character-count field (whose length depends on the version), then the packed data, then a 4-bit terminator 0000, padded to a byte boundary and filled with alternating pad bytes 0xEC, 0x11.

Why this matters: a URL like HTTPS://EXAMPLE.COM in alphanumeric mode takes roughly half the modules of byte mode โ€” which can drop you a whole version size. Good QR generators pick the most efficient mode automatically; naive ones use byte mode for everything and produce unnecessarily dense (hard-to-scan) codes.

ECI (Extended Channel Interpretation) mode switches the character set โ€” most importantly, it signals UTF-8 for non-Latin text. Without ECI, byte mode is conventionally ISO-8859-1, which is why some scanners garble emoji or CJK text: the encoder and decoder disagreed about the charset.

Error Correction: Reed-Solomon to the Rescue

This is the engineering marvel. QR codes use Reed-Solomon error correction โ€” the same family of codes protecting CDs, DVDs, and deep-space communications. The data is divided into blocks; for each block, the encoder computes error-correction codewords (polynomials over GF(256)) and interleaves them with the data. A scanner with a damaged symbol solves for the missing pieces algebraically.

Four levels, chosen at generation time:

Level Recovery capacity Use when
L ~7% of codewords Clean prints, controlled lighting
M ~15% General purpose (the default)
Q ~25% Industrial environments, some damage expected
H ~30% Logos embedded in the code, harsh conditions

The tradeoff is capacity: level H reserves far more modules for correction, so the same version holds less data. A version-40 code holds 7,089 numeric characters at level L but only 3,057 at level H.

This is why you can stamp a logo in the middle of a QR code and it still scans โ€” you're destroying data modules, and Reed-Solomon reconstructs them, as long as the damage stays under the level's threshold. (Keep the logo under ~15% of the area at level H, and never cover the finder patterns.)

Masking: Breaking Up Bad Patterns

After data placement, the encoder XORs the modules with one of 8 mask patterns (repeating geometric formulas) and picks the mask with the lowest penalty score. Why? Certain module arrangements confuse scanners: large solid blocks (no edges to lock onto), or patterns that mimic finder patterns. Masking breaks these up. The chosen mask number is stored in the format information bits so the decoder can undo it. This step is invisible to users but it's why two QR codes with the same data can look different.

Capacity: How Much Fits?

Maximum capacities (version 40, the largest):

Mode Level L Level M Level Q Level H
Numeric 7,089 5,596 3,993 3,057
Alphanumeric 4,296 3,391 2,419 1,852
Byte 2,953 2,331 1,663 1,273

For a typical URL (~60 bytes) at level M, a tiny version-3 or 4 code suffices โ€” which is why most QR codes you see are small. If your generator produces a dense, hard-to-scan code for a short URL, it's probably using byte mode with level H unnecessarily.

Common Mistakes

1. Too much data, too small a print. Density has physical limits: a version-10 code printed at 1cm wide has modules ~0.2mm across โ€” below what phone cameras resolve reliably. Rule of thumb: modules should be โ‰ฅ0.5mm for reliable scanning; scale the print size with the data.

2. Inverted colors. QR is defined as dark modules on a light background. Light-on-dark sometimes works with modern scanners but is explicitly discouraged by the spec and fails on many readers. Keep the contrast high and the background light.

3. Covering finder patterns. The three corner squares are sacred โ€” a logo overlapping them kills scanning instantly. Center placement only.

4. Low error correction + logo. Level L with a 20% logo = dead code. Match the level to the damage: any embedded artwork demands level H.

5. Quiet zone violations. The spec requires a 4-module-wide quiet margin around the symbol. Text or design elements touching the code's edge break detection. Generators include it; designers crop it off.

6. Encoding URLs in the wrong mode. Lowercase URLs can't use alphanumeric mode (it's uppercase-only) โ€” but the domain can be uppercased since DNS is case-insensitive. Smart encoders split the data into segments with different modes to minimize size.

Debugging Walkthrough: "It Won't Scan"

  1. Check the quiet zone. Is anything touching the code's border? Add white margin.
  2. Test contrast. Photograph it and convert to grayscale โ€” if modules don't separate cleanly into black/white, the scanner can't either. Red-on-white is a classic failure (red reads as light gray to many sensors).
  3. Reduce density. Regenerate with a higher error-correction level and a larger version, then print bigger. Most scan failures are physical, not logical.
  4. Verify the content. Decode with a different scanner app โ€” if one reads it and another doesn't, the content is fine and the failing scanner is at fault (often an outdated app).
  5. Check for damage over the threshold. If >30% of the symbol is obscured or the finder patterns are damaged, no level of correction saves it โ€” regenerate and reprint.

Try It

Theory is nice; generating one is better. DailyToolbox's free QR code generator runs entirely in your browser โ€” create QR codes for URLs, text, and contact cards with adjustable error correction levels, no data leaving your device.

๐Ÿ‘‰ Generate a QR code โ†’

FAQ

Are QR codes secure?

The code itself is just data โ€” it can encode a malicious URL as easily as a benign one (a practice called "quishing"). Scanners can't verify intent. Never scan QR codes from untrusted sources without previewing the URL, and be wary of QR stickers placed over legitimate ones.

What's the difference between static and dynamic QR codes?

A static QR encodes the destination directly (the URL is in the code). A "dynamic" QR encodes a redirect service's URL โ€” the service forwards to your real destination, letting you change the target later and track scans. The tradeoff: dynamic codes depend on the redirect service staying alive, and the service sees your traffic.

Why do some QR codes have rounded or styled modules?

Styling (rounded dots, brand colors) is cosmetic โ€” it works as long as modules remain distinguishable and contrast stays high. Aggressive styling reduces the effective error margin, so pair it with level H and test on multiple scanner apps.

Can a QR code store binary data like images?

Technically yes (byte mode holds ~3KB max), but it's pointless โ€” 3KB doesn't fit any useful image, and the resulting code is extremely dense. QR codes are for pointers (URLs, identifiers), not payloads. Put the image on the web and encode the link.

What are Micro QR codes?

A compact variant (ISO/IEC 18004) for small applications, with versions M1โ€“M4 (11ร—11 to 17ร—17 modules) and a single finder pattern. They hold far less data (up to 35 numeric characters) and need less space โ€” useful for tiny electronics labeling. Most phone scanners read them fine.

#qr-code#encoding#error-correction#algorithms#data-encoding
AS
Written by Alex Sun

Alex Sun is the developer behind Daily Toolbox. He writes these guides while building the tools themselves โ€” every claim tested against the real thing.

Try the free tools mentioned above

Try the QR Code Generator โ†’