How QR codes work

I structured this article so it requires no prior knowledge but still covers every detail. To do that, we follow one concrete QR code encoding "https://qrboat.app/how-qr-codes-work" throughout (with error correction level H). Every figure and number here is computed from it. All rules and constants are checked against the ISO/IEC 18004 specification.

The QRBoat mascot, a small boat pondering with two question marks above

Anatomy

A QR code is a grid of dark and light squares called modules. The grid as a whole is a symbol, and every module in it is placed by a rule.

Less than a quarter of this one is your data. The function patterns and the format information are fixed by the version alone, so they are identical in every symbol of that size. The rest is the data region. Four things share it. The message is the payload with its mode headers and the terminator that closes the stream. Error correction is parity codewords. The level sets how many there are, whatever the message is, which is why a short message in a large symbol is mostly padding: two bytes alternating until the capacity is full. The remainder is the few modules past the last codeword, because the data region doesn't always divide into whole eight-module codewords. They are placed and masked like any other and carry nothing.

Encode with
error correction.
    • Message 304 22%
    • Padding 64 5%
    • Error correction 704 51%
    • Remainder 7 1%

Symbols come in 40 sizes, and the specification calls them versions 1 to 40. The three finder patterns cost the same at every one of them, so the larger the symbol, the smaller their share of it. Alignment patterns are added in a widening grid from version 2, and version information from version 7.

The mathematics

A version V symbol is 4V+17 modules across, so the 40 versions run from 21 to 177 modules a side, or 441 to 31,329 modules in all. The width already tells a reader the version, so version information is only added from version 7 on. From there a wide symbol is easy to miscount, and avoiding that is worth the 36 extra modules.

From version 2, alignment pattern centers sit at ⌊V/7⌋+2 positions along each axis. Every pair of positions carries a pattern except the three at the finder corners, so a symbol has (⌊V/7⌋+2)2−3 of them: 1 at version 5, and 46 at version 40.

VersionModulesFunction modulesShare
144123353%
51,36929021%
4031,3291,6815%

Finding the code

A reader locates the symbol before it knows the version, the angle or the module size. It scans the image for a specific ratio. A line drawn across a finder pattern through its center crosses five unbroken runs (dark, light, dark, light, dark) in the proportion 1:1:3:1:1. Turning or scaling the pattern multiplies all five runs by the same factor, so the proportion holds. This is also the case for tilting: from a distance the whole symbol sits at nearly one depth, so a tilt compresses the finder uniformly and the ratio stays intact; up close, where perspective and lens distortion are stronger, the ratio might shift past a reader's tolerance. Three matches in the right relative positions fix three of the symbol's corners and its rotation.

Since a reader matches the ratio, a finder pattern can be drawn as a rounded square, a circle or a set of separate pieces: a line through the center still crosses five runs in the same proportion. The standard specifies a square finder; the other shapes work only because readers tolerate them, and only while the center line stays intact. A light gap across the middle splits the center run in two: five runs become seven, and nothing matches 1:1:3:1:1.

Three finders give a reader nothing but a position, a rotation and a scale. The timing patterns supply the module pitch: a line of alternating dark and light modules between the finders, which a reader counts along (instead of measuring distances against a module size it would have to guess). The alignment patterns are known points inside the symbol, so a reader can correct the perspective a photo introduces. Outside the symbol, the quiet zone is four modules of blank margin on every side, so that ink printed next to the code can't be taken for modules. Four modules are a hard requirement of the specification, but readers manage on less.

11311::::

Two variations remain: a symbol may be printed light on dark, and it may arrive mirrored. The standard makes both optional and gives its decoding procedure a step for each.

Printed light on dark, every module swaps color and the quiet zone swaps with them: the margin is the symbol's background continued outwards, so it goes the way the light modules go. A reader works out which way round it is from a finder pattern, whose coloring it already knows. The center run of three is dark in an ordinary symbol, so a light one means the image is reversed and every module in it reads the other way.

A code photographed through glass from behind arrives mirrored. Which axis it was flipped about makes no difference: a square has four mirror images and each is a rotation of the others, so a reader that already ignores rotation has one case to handle. That case is the symbol with its rows and columns swapped.

Every function pattern is symmetric about that diagonal, so a transposed symbol still looks well formed. Only the data and the format information move, and the format information settles it: a reader reads the 15 bits and tries to correct them. If neither copy corrects to a word the code can produce, it swaps rows and columns and reads them again.

Neither is required of a reader. Our tester runs rxing, which reads a mirrored symbol with no hint set and no extra effort allowed, and refuses a reversed one until it's told to try the image inverted. Mirroring costs that decoder nothing; light on dark costs it a hint, which not every reader gives.

The mathematics

The finder pattern is three concentric squares about one center. A line through that center at angle θ meets a square of half-width s at distance s/max⁡(|cos⁡θ|,|sin⁡θ|). The factor depends on θ alone and not on s, so every run along the line is stretched by the same amount and the ratio of the five is preserved. At 45∘ it's 2, about 1.41: the runs measure 1.41, 1.41, 4.24, 1.41 and 1.41 modules.

Transposed and read as though it were upright, this symbol's two format copies land 4 and 5 bits from the nearest word the (15, 5) code can produce. It corrects three, so both fail.

The worked symbol, dark modules on light paper.
As drawn
The same symbol light on dark, with the quiet zone dark as well.
Reversed
The same symbol with rows and columns swapped, so the finder pattern that was at the top right is now at the bottom left.
Mirrored
The same symbol light on dark and with rows and columns swapped.
Both

Encoding

The content becomes bits before it's placed, and what a character costs depends on which of four modes it's written in. Fewer bits can mean a smaller symbol, so an encoder picks the cheapest mode the content allows.

  • Numeric 0 to 9 3 characters in 10 bits
  • Alphanumeric 0 to 9, A to Z, space and $ % * + - . / : 2 characters in 11 bits
  • Byte e.g. UTF-8 text 1 characters in 8 bits
  • Kanji the Shift JIS double-byte range 1 characters in 13 bits

Every segment opens with four bits naming its mode: 0001 numeric, 0010 alphanumeric, 0100 byte, 1000 kanji. A reader reads them before anything else in the segment, because they set the width of the character count field that follows.

NumericAlphanumericByteKanji010020030015101517VersionCharacters
A step chart. Characters run left to right to 300 and version rises upward. One line per mode, each stepping up wherever a version fills. 300 characters is version 8 in numeric mode, version 10 in alphanumeric mode, version 13 in byte mode, version 17 in kanji mode.
Where each mode crosses into the next version, at level M. Read up from a character count to the smallest symbol that holds it.

This page's address, 36 characters in lowercase, needs version 3. Uppercased, the same 36 characters fit version 2, because capital letters are in the alphanumeric set and lowercase letters are not. The scheme and the host of a URL are case insensitive, so uppercasing them costs nothing. A path is case sensitive, and uppercasing it points at something else.

Both symbols above are at error correction level M, and the worked example is at level H, so the same address makes a larger symbol elsewhere on the page.

The address of this page as a QR code, version 3.
Lowercase, byte mode, version 3.
The same address uppercased as a QR code, one version smaller.
Uppercased, alphanumeric mode, version 2.

The bits form one stream. In byte mode it opens with a four-bit mode indicator, then the character count in eight bits, then one byte per character. Up to four zero bits close the message, fewer if the symbol is nearly full. The stream is then padded out to a whole number of codewords, the eight-bit unit every later step works in. This symbol holds 46 data codewords: the address and its headers take 38, and the remaining 8 are two fixed pad codewords, alternating, so a short message ends in a visibly repeating pattern.

Byte mode's default character set is Latin-1, which covers western European languages and nothing else. So when the content leaves ASCII the encoder names UTF-8 instead of leaving a reader to assume the default: an ECI header, 12 bits naming assignment 26, ahead of the first segment. Characters then cost what UTF-8 charges for them: an accented letter is two bytes and an emoji four, against one for an ASCII character.

The mathematics

Ten bits hold three digits because 999<210, which is 313 bits a digit. Eleven hold two alphanumeric characters because 452=2025<211, or 512 each. Kanji mode's 13 bits beat the 16 the same character costs as two bytes.

This symbol's stream is 4+8+36×8=300 bits, plus the terminator, which rounds up to 38 codewords.

Capacity is what the data codewords hold once the headers are paid for, which is why the 46 data codewords here carry 44 bytes rather than 46, of which this address uses 36. Version 40, the largest, holds at each level:

LevelDigitsAlphanumericBytesKanji
L7,0894,2962,9531,817
M5,5963,3912,3311,435
Q3,9932,4201,6631,024
H3,0571,8521,273784
0100 Byte mode
00100100 36 characters
01101000 "h"
01110100 "t"
01110100 "t"
01110000 "p"
… 32 more
0000 Terminator
11101100 00010001 8 pad codewords
The stream in order: the mode indicator, the character count, one byte per character, the terminator, then the pad codewords.
This symbol's stream, field by field. 38 codewords carry the address and its headers, 8 are padding.

A symbol need not be written in one mode. The stream is a sequence of segments, each opening with its own mode indicator and character count, and a reader switches modes as it reads. So the cheapest way to write mixed content is usually a mixture, and the digits in a link can be encoded more cheaply than as text.

Every segment costs four bits of indicator plus its character count field, so a short run is cheaper left where it is. That's also why the boundaries don't fall where the eye would put them: the slash before the reference goes into the alphanumeric run, because a slash is in that set and moving it there costs nothing.

The encoder behind this site picks one mode for the whole string. The split above is computed separately and checked against exhaustive search.

The mathematics

A segment of n characters costs 4+c(M,V)+⌈rMn⌉ bits: four of mode indicator, then the character count field c(M,V), then rM bits a character. The ceiling is taken at the segment boundary, the one place the stream aligns to a whole bit, so the running cost is carried in sixths of a bit and rounded only there.

A greedy split doesn't work, because whether a run earns its own segment depends on a header whose width depends on the version. So the split is a dynamic program over positions and modes: fi(M) is the fewest bits for the first n characters ending in mode M, and fi(M)=min⁡(fi−1(M)+rM, minM′⁡⌈fi(M′)⌉+4+c(M,V)).

Character count widths, ISO/IEC 18004 Table 3. The width is what couples the two searches: it depends on the version, the version on the total, the total on the split. Inside a band the split can't change, so it's computed once per band and the version search runs within it.

Mode1 to 910 to 2627 to 40
Numeric101214
Alphanumeric91113
Byte81616
Kanji81012
https://qrboat.app/r Byte 20 characters, 172 bits
/QRB-2026- Alphanumeric 10 characters, 68 bits
8613612345678901 Numeric 16 characters, 68 bits
The link split into 3 runs, each in the color of the mode it was written in: the host and path in byte mode, the uppercase reference in alphanumeric, the digits in numeric.
308 bits in 3 segments, against 380 as one byte segment. Version 3 rather than version 4.
https://qrboat.app/r/42 Byte 23 characters, 196 bits
The same shape of link with only two digits at the end, left as a single byte mode run.
A separate segment for two digits saves nothing: 196 bits either way, so the encoder keeps the link as one segment.

Error correction

A damaged symbol still reads, because most of it is not the message. The symbol this page works through, version 5 at error correction level H, holds 134 codewords: 46 are data, the message with its padding, and the other 88 are Reed-Solomon parity computed from them. A reader reconstructs the codewords it couldn't read from the ones it could.

A checksum only says that something is wrong. The parity says which part. The encoder treats the data codewords as the coefficients of a polynomial and picks the parity so that data and parity together divide exactly by a fixed generator. A reader divides what it received: no remainder means the block is intact. If there's one, solving it gives which codewords are wrong and the values they should have held.

Locating one wrong codeword and correcting it costs two parity codewords, one to find it and one to fix it. A reader that already knows which codeword it failed to read needs only one.

The same algorithm runs on every block separately. The 134 codewords of our example are divided into 4 blocks of 11 or 12 data codewords and 22 parity codewords. Each block is corrected on its own, up to 11 wrong codewords in it, no matter what the other blocks hold. If one block has more than 11, the symbol doesn't decode.

The blocks are uneven because the data codewords don't divide by 4. The specification puts the short ones first.

How much parity a symbol carries is chosen before anything is encoded. There are four levels, and a higher one trades capacity for tolerance in a symbol of exactly the same size.

The 7, 15, 25 and 30 percent usually quoted for the four levels are nominal. The shares in the table are measured on this version, and they are shares of the 134 codewords rather than of printed area.

The mathematics

A codeword is an element of the field GF(28): a byte, with addition as XOR and multiplication modulo x8+x4+x3+x2+1. A block of k data codewords is the coefficient list of a polynomial m(x), and the generator for 2t parity codewords is g(x)=(x−α0)(x−α1)⋯(x−α2t−1), with α=2. The parity is the remainder of m(x)⋅x2t divided by g(x), so the complete block is divisible by g.

A decoder evaluates the received block at α0 to α2t−1. All zeros means no errors. Otherwise 2t parity codewords locate and correct t errors at unknown positions, or fill 2t erasures at known ones. Here k is 11 or 12 and 2t is 22, so t is 11.

Block 1 of this symbol, read off the modules. The first data codeword, 0x42, is the mode indicator and the top half of the character count.

Data42 46 87 47 47 07 33 a2 f2 f7 17
Parity0a 44 f1 e0 8a 95 8b 36 4e 60 cf e2 1c 26 2d 6a 28 dc 36 1d 4f 14
The four error correction levels, measured on this version.
LevelDataData and parityCorrectsShareBlocks
Llow108 108 data, 26 parity1310%1
Mmedium86 86 data, 48 parity2418%2
Qquartile62 62 data, 72 parity3627%4
Hhighthis symbol46 46 data, 88 parity4433%4

Corrects sums what each block corrects on its own. It's an upper limit: a symbol reaches that total only when the damage is spread evenly across the blocks.

The eight modules of one codeword stay together in a two-wide stack along the placement order, and the codewords before and after it in the stream belong to the other blocks.

The stacks aren't all the same shape, and the shape comes from the placement order, not from the block.

A square of the symbol with every codeword drawn to its own outline, one of them ringed in the accent color. Each outline encloses eight modules in a compact two-wide group rather than a row or a scattering, some of them stepped by one module at each end. The codewords above and below the ringed one are in other blocks and other colors.
Every codeword to its own outline, one of them ringed: eight modules together, with its neighbors in the stream in the other 3 blocks.

The blocks are interleaved: the stream takes the first codeword of block 1, then the first of block 2, and so on until all 4 blocks are spread over the whole symbol. Damage in one place is then shared out between the blocks, and each loses only a few codewords.

Parity is spent per codeword touched, not per module. A smudge covers whole codewords; a scatter of the same area touches a different codeword with every module. Measured on this symbol, the code still decodes with the patch the demo starts with, wherever the patch is placed, and that patch covers up to 184 data modules. Spread evenly, 32 modules are enough to lose a block.

A logo affects a symbol the same way: it covers whole codewords in one place, and the same parity has to repair them.

Both counts are of data modules only. A smudge over a finder pattern is a different failure: parity covers nothing outside the data region.

The mathematics

Interleaving: with B blocks, position p of the stream holds codeword ⌊p/B⌋ of block pmodB, until the short blocks run out; the parity codewords are interleaved the same way after the data.

Each data module colored by the block it belongs to.

Drag the smudge, or move it with the arrow keys.

Codewords hit in each block.
BlockCodewords hit
1 7 / 11
2 8 / 11
3 8 / 11
4 8 / 11

Every block is within its limit. The symbol still decodes.

Placement

The interleaved stream goes into the grid in a fixed order: two columns at a time, starting at the bottom right corner, upwards through one pair of columns and downwards through the next, skipping the function patterns.

That order is a property of the version and not of the message, so a reader can walk it before it knows the mask, the level or the content.

The 8 pad codewords sit at the end of the message, but not at the end of the walk: interleaving spreads that end over the whole symbol.

All 134 codewords placed. The last 7 modules of the walk belong to no codeword.

One step of the walk takes the right module of a row and then the left one beside it, and the step after it is one row along. A pair is climbed or descended whole, and the turn comes where the data runs out at the top or the bottom.

8 modules taken that way fill four rows of a pair, which is where the codeword shapes come from. The one picked out here is offset at both ends: it begins on a left module, so it starts half a row in, and the data runs out above it, so its last module is the first module of the next pair.

A pair steps over the vertical timing pattern whole, so the direction of travel doesn't reverse where the pattern sits.

The mathematics

Number a column c from the right edge, leaving the vertical timing pattern out of the count. The pair it belongs to is ⌊c/2⌋, and that pair is climbed when ⌊c/2⌋mod2=0 and descended otherwise.

Nine by nine modules of the worked example with the placement order drawn over them: the line takes the right module of each row before the left, climbs one column pair, steps over the vertical timing pattern whole and descends the next pair, with one codeword picked out across the turn.
The same walk, nine modules across. The picked-out codeword runs from the ring to the arrow: half a row, three whole rows, then one module in the next pair.

The data region is 1,079 modules and the 134 codewords take 8 each, or 1,072. That leaves 7 modules at the end of the order, too few for another codeword. The specification calls them remainder bits: they are placed and masked like any other module, and a reader drops them.

Masking

Placed straight into the grid, the data can form three problem patterns: a large area of one color, a long run along a row or a column, a sequence in the 1:1:3:1:1 proportion a reader would take for a finder pattern. So the encoder applies a mask after placing the data: a fixed geometric pattern naming which data modules to invert.

Applying a mask is an exclusive or: where the pattern is on, the module comes out the other color; where it's off, the module stands as placed. No mask touches the function modules: the finder and alignment patterns, the timing patterns, the separators around the finders, the format information beside them. That exemption is what lets a reader trust them before it knows which mask was used. There are eight patterns. The encoder scores every one on four rules, and the lowest total wins.

Runs
Five or more modules of one color along a row or a column. 3 points, and one more for every module past the fifth.
Blocks
Every two by two square of one color. 3 points each.
Finder-like
Every 1:1:3:1:1 sequence with four light modules beside it, which looks like a finder pattern. 40 points each.
Balance
How far the share of dark modules is from half. 10 points for every 5% step outside 45 to 55.

The eight totals here run from 1634 for mask 4 to 1830 for mask 6, and the data as placed, with no mask at all, would score 1755: lower than 6 of the eight. The encoder can't know in advance which content produces these patterns, so it scores all eight every time; on content that would otherwise leave a large blank area, the mask breaks it up.

The score is taken over the whole symbol, so a real finder is charged for looking like one: 18 of the winning mask's 21 finder-like sequences are the three finders themselves, and 3 fall in the data. The balance rule scores zero for every candidate, which leaves the first three to decide it.It costs nothing between 45% and 55% dark: the placed data is already at 49.6%, and the eight candidates land between 49.5% and 53.2%.

The mathematics

Runs and finder-like sequences are scored on rows and columns independently, so a shape lying on both axes is charged twice. A two by two block is counted once per top left corner, so a solid area of n by n modules costs (n - 1)² of them.

The mask:
  • inverted
  • unchanged
  • exempt
Mask 4. Total 1634, the lowest of the eight, so this is the mask the encoder applies.
The placed data and the eight mask candidates, scored on the four rules. Each score bar runs from zero to the highest in its own column. Pick a row to show it above.
MaskFlips a module whereRunsBlocksFinder-likeBalanceTotal score
406 429 920 0 1755
(i+j)mod2=0442 495 840 0 1777
imod2=0451 471 840 0 1762
jmod3=0434 429 920 0 1783
(i+j)mod3=0416 468 880 0 1764
(⌊i/2⌋+⌊j/3⌋)mod2=0365 429 840 0 1634
(i⋅j)mod2+(i⋅j)mod3=0404 453 960 0 1817
((i⋅j)mod2+(i⋅j)mod3)mod2=0437 513 880 0 1830
((i+j)mod2+(i⋅j)mod3)mod2=0421 438 840 0 1699

A reader has to know which mask to undo before it can read anything, so the mask number is stored in the symbol unmasked. The format information is 15 bits beside the finder patterns, written twice: two bits of error correction level (10 for level H), three of mask number (100 for mask 4), then ten check bits computed from those five. All 15 are then combined with a fixed word, so that no combination of level and mask comes out all zeros. The code corrects up to three wrong bits in each copy.

The mathematics

The check bits are the remainder of the five data bits, shifted left by ten, divided by the generator x10+x8+x5+x4+x2+x+1. That's a (15, 5) BCH code: 32 valid words, any two of which differ in at least seven bits, so three errors are correctable. The level bits don't run in the order of the levels: L is 01 and M is 00.

The format word of this symbol: the data and check bits combined with the fixed word to give the 15 bits written into the symbol.
Data and check bits10 100 1101110000
Fixed word10 101 0000010010
Written00 001 1101100010

Groups: level (2), mask (3), check bits (10).

Reading it back

A reader runs the steps above in reverse. Pick a step to see what a reader has at that point.

  1. Three 1:1:3:1:1 sequences at the right relative positions give the corners and the rotation (finding).

  2. The timing patterns give the module pitch and the alignment patterns correct the perspective. One bit is then sampled per module.

  3. Correct up to three bits in it, and take the error correction level and the mask number (masking).

  4. Invert every data module the mask selects.

  5. Read the bits along the placement order into codewords, and sort them back into their blocks (error correction).

  6. Every block is corrected on its own, against its own parity.

  7. Segment by segment, each with its own mode and count, until the terminator or the end of the data (encoding).

Those seven steps account for every module: 21% function patterns and format information, 22% address, 5% padding, 51% error correction. The 7 modules left over at the end of the placement order are dropped.

Three finder patterns, 147 modules. Which corner has none gives the rotation.

Origins

The code was developed at Denso by a team led by Masahiro Hara and announced in 1994. The problem was parts tracking. A barcode holds around 20 characters, so a box of parts carried several of them, and a worker on the line was scanning about 1,000 times a day.

The grid came from a board game. Hara has said that he played Go in his lunch breaks at the office, and that arranging black and white stones on a grid struck him as a simple way to hold information. He said the same again in 2025, when the Japan Go Association made him a Go ambassador.

The team found the 1:1:3:1:1 ratio by surveying printed matter (flyers, magazines, cardboard) for the proportion of dark and light that occurs least often, so that a search for the pattern would rarely match the print around the symbol.

AIM standardized the code in 1997 and JIS in 1999. ISO followed in 2000, as ISO/IEC 18004, the specification this page cites.

DENSO WAVE holds patents on the QR Code and has declared that it will not exercise them against codes that follow the JIS or ISO standard. Hara's stated reason was that one company couldn't build the infrastructure fast enough on its own. So making a QR code to the standard needs no license from DENSO WAVE.

"QR Code" is a registered trademark of DENSO WAVE INCORPORATED in Japan and other countries. QRBoat is not affiliated with, endorsed by or connected to them.

Sources