Polyatic

QR Codes Explained

A QR code looks like random noise, but almost none of it is random. It is a two-dimensional matrix barcode — a grid of black and white squares that stores data along both axes instead of in the width of stripes, which is why it holds far more than the one-dimensional barcode on a cereal box. Invented in 1994 by Denso Wave to track car parts, it is now defined by the international standard ISO/IEC 18004. This guide takes one apart from first principles: the fixed patterns a scanner hunts for, the blank margin it needs, the four ways your text is packed into bits, how the grid grows, the four error-correction levels, and the Reed–Solomon maths that lets a torn or logo-covered code still read.

The single black or white square in a QR code is called a module. A scanner cares only whether each one is dark or light, not how many pixels or millimetres it spans — which is why the same code works on a phone screen, a business card, or a billboard. Some modules are fixed scaffolding, some carry your data, and some carry error correction that repairs the data if part is lost.

The fixed patterns: scaffolding a scanner can find

Before a scanner can read a single bit of your content, it has to locate and orient the code in a camera frame that may be rotated, skewed or badly lit. Structural patterns identical in every code make that possible:

  • Three finder patterns — the big square "bullseyes" in the top-left, top-right and bottom-left corners. Each is a 7×7 module ring with a consistent 1:1:3:1:1 dark-light ratio along any line through its centre. That ratio is rare in natural images, so a reader spots the three squares fast and, because there are exactly three (not four), works out which way is up.
  • Alignment patterns — smaller 5×5 rings that appear from version 2 onward, more of them in larger codes, letting the scanner correct for perspective distortion when the code is photographed at an angle or printed on a curved surface.
  • Timing patterns — a single row and column of alternating dark-light modules running between the finders. They act like a ruler, telling the reader the exact module pitch so it can count grid lines even when the image is stretched.
  • Format information — a small band of modules near the finders recording which error-correction level and mask were used, so the decoder knows how to read the rest.

Only after that scaffolding is found does the reader walk the remaining modules to recover your data. It costs modules that could have held content, but it is what makes a QR code readable from any angle almost instantly.

The quiet zone: the margin that isn't optional

Around every QR code is a mandatory blank margin called the quiet zone, at least four modules wide on all sides. It is not decoration — the scanner uses that uniform light border to tell where the code ends and the busy background begins. Crop a code tight to its edge, or set it on a patterned surface with no margin, and readers that could otherwise decode it perfectly will simply fail to find it. It is the single most common reason a technically valid code won't scan.

Four encoding modes — and why the mode sets capacity

A QR code stores bits, not characters, and how efficiently your text becomes bits depends on the mode the encoder picks. The standard defines four, each tuned to a different alphabet:

ModeAlphabet it handlesBits per character
Numericdigits 0–9 only~3.33 (10 bits per 3 digits)
Alphanumeric0–9, A–Z (capitals), space and $ % * + - . / :~5.5 (11 bits per 2 chars)
Byteany byte, i.e. arbitrary UTF-8 text8
KanjiShift-JIS Japanese characters13

The narrower the alphabet, the fewer bits each character needs, so the more characters fit the same grid. Byte mode spends a full 8 bits per character because it must represent anything, while numeric squeezes three digits into 10 bits — which is why a phone number encodes into a much smaller, easier-to-scan code than the same count of letters, and why an encoder always uses the most restrictive mode your content allows.

Worked example: HELLO vs a URL

The word HELLO is all capital letters, every one in the alphanumeric set, so it encodes in alphanumeric mode at about 5.5 bits per character — roughly 28 bits for the five letters. Compare a real link:

"HELLO" every char is in the alphanumeric set (A–Z) → alphanumeric mode, ~5.5 bits/char → ~28 bits "https://polyatic.com/" lowercase letters + "//" are NOT in the alphanumeric set → must fall back to byte mode, 8 bits/char → 168 bits

The URL's lowercase letters aren't in the alphanumeric set, so the encoder falls back to byte mode and spends a full 8 bits on every one of its 21 characters — several times the bits for a similar character count. This is why keeping a QR payload short and, where possible, uppercase-and-numeric produces a smaller, more scannable code.

Versions: how the grid grows

QR codes come in 40 standard sizes called versions. Version 1 is 21×21 modules, and every step up adds four modules to each side: version 2 is 25×25, version 3 is 29×29, on up to version 40 at 177×177. More content, or a higher error-correction level, forces a larger version. The trade is physical: a low version has big, bold modules that scan easily at small print sizes, while a version near 40 is so dense it demands a large, crisp print. A good encoder always uses the smallest version that fits your data at the chosen level.

The four error-correction levels

Part of every QR code is deliberately redundant: it carries extra error-correction data so the content survives smudges, tears, or a logo dropped on top. The standard defines four levels, their recovery capacities fixed by the QR specification:

LevelRecovers up toBest for
L (Low)~7% of the codeclean screens, digital display
M (Medium)~15%general use — the common default
Q (Quartile)~25%print handled outdoors
H (High)~30%logo overlays, harsh conditions

Those four figures — roughly 7%, 15%, 25% and 30% — are the spec-defined values, not a rule of thumb; they measure the fraction of total codewords that can be lost or wrong while the message stays perfectly recoverable.

The honest capacity-vs-resilience tradeoff

Error correction is not free — every redundant module is one that cannot hold your content. In a fixed-size grid, choosing level H instead of L roughly halves how much data fits, because far more of the grid is spent on recovery. So it is a genuine tradeoff: hold the version fixed and higher correction means less capacity; hold the content fixed and it means a larger, denser code. There is no universally best level — match it to how the code will be handled.

Why a damaged or logo-covered code still scans

The error correction is Reed–Solomon coding, the same family of maths used on CDs and deep-space probes. It adds redundant "check" codewords that over-describe the data, so a decoder can rebuild the message even when some codewords are missing or wrong — as long as the damage stays within the level's budget (about 7% at L, up to 30% at H).

This is why a company logo in the middle of a QR code still reads: the logo destroys some modules, but as long as the lost fraction is under the budget, Reed–Solomon fills them back in — the same reason a code survives a coffee ring, a crease, or a partly torn poster. The catch is the same tradeoff: a logo covering more than the budget breaks the code, which is why logo codes use level H and keep the logo modest.

Generate a QR code right now

Type a link, WiFi login or contact card and watch it encode live, with an error-correction selector and a capacity meter that shows the exact version your content needs — everything runs in your browser, nothing is uploaded.

Try the QR Code Generator →

Putting it together

A QR code stops looking like noise once you can name its parts: three finder squares plus timing and alignment patterns let a scanner find and orient it, the four-module quiet zone marks its edge, your text is packed into bits by the narrowest mode that fits its alphabet, the grid grows in 4-module steps from 21×21, and a slice of every code is Reed–Solomon redundancy that repairs damage up to the L/M/Q/H budget. Keep the payload short, leave the quiet zone alone, and match the error-correction level to the job.

Open the QR Code Generator → and watch the version and capacity meter respond live, or browse all Polyatic tools.