You hold the phone at an angle, because you are sitting down and the sticker is on the table. The laminate is scuffed from a thousand wipe-downs. There is a water ring across one corner where somebody’s glass sat, and the overhead light is throwing a glare over half the square. You do not line anything up. You do not hold still. In somewhere under a second, it makes a small sound and a menu appears on your phone.
Nothing about that should work. The camera has no idea which way up the thing is. Part of the pattern is obscured and part of it is distorted by the angle you are holding the phone at. And yet the failure rate, in ordinary use, is so close to zero that you have probably never thought about it — which is the strongest evidence I can offer that the design is doing something clever.
It is. But the cleverness was not aimed at you, and it was not aimed at a restaurant table. Every decision in the original design of the QR code was made by one engineer, solving a problem on a factory floor in Japan in 1992, and the format still bears the shape of that problem the way a tool bears the shape of a hand.
What its inventor was actually solving
Masahiro Hara was an engineer at Denso, the auto-parts arm of the Toyota Group, and in 1992 he was working on barcode scanners.1 Barcodes were everywhere by then and they were not enough. A single barcode carries about 20 alphanumeric characters, and an automotive part identifier is longer than that, so a part might need 5 to 10 barcodes to describe it. Workers on the line were scanning on the order of a thousand of them a day. Their job had effectively become barcode reading.
The other problem was that barcodes could not represent the characters and symbols used in Japanese writing — kanji and kana. The operators were Japanese, the paperwork was Japanese, and the format could not hold the language of the people using it.
So the brief was narrow and specific. Hold much more data. Print small, because the parts were getting smaller. Read fast — the “QR” is for Quick Response, and it means throughput on a moving line, not convenience for a consumer. Read at any angle, because nobody is going to square up a box for you. Survive oil, grease, scratching and tearing, because that is what the factory does to a label. Handle Japanese writing natively.
Every one of those requirements is still visible in the code on your menu. None of them was about you.
The two-dimensional idea, Hara has said, came to him while playing Go — a game of black and white stones on a grid, information sitting in a field rather than along a line. It’s both a pleasing origin story and an accurate description of the data structure.
The ratio that isn’t in newsprint
Reading fast at any angle creates a problem that has nothing to do with data. Before a scanner can decode anything, it has to find the code and work out its orientation, and it has to do this on an image that also contains a cardboard box, a printed label, a shipping manifest, and whatever else is in frame. Searching the whole image for a grid is expensive. Hara needed a marker that a scanner could spot in a single cheap pass, and that would never be produced accidentally by anything else in the picture.
He went looking for it empirically. Over roughly six months, he and his team photographed printed matter — newspapers, magazines, flyers, business documents — and analyzed the black-and-white run lengths they contained, hunting for a sequence that print does not naturally produce.
What they found was 1:1:3:1:1. Scan a line across the big square in the corner of a QR code, in any direction, and the widths of the alternating dark and light runs come out in that proportion. It is, apparently, a ratio that essentially never occurs by accident in printed material. Hara’s own assessment is unambiguous: without this ratio, there would have been no QR code.2
The finder pattern, in other words, was not designed. It was found, by six months of looking at newspapers.
And there are three of them, not four, which is the second half of the trick. Four markers at four corners would be rotationally symmetric and the scanner would have no way to tell which way up it was looking. Three markers break the symmetry. The scanner finds the three, infers where the missing fourth corner would be, and from that alone it has the code’s position, its rotation, and — because the three form a right triangle of known proportions — the perspective distortion introduced by your hand holding the phone at an angle. Orientation independence is not a feature bolted on. It falls out of the decision to use three corners instead of four.
Modules, not bits
The rest of the design is easier to follow with one distinction in place, because almost every popular explanation of QR codes gets it slightly wrong.
The individual squares in the grid are called modules. A module is not a bit. Some modules carry no payload at all: the three finder patterns, the timing patterns that run between them like a ruler, the alignment patterns that help the scanner correct for curvature in larger codes, and dedicated regions holding format and version information. Beyond that, even the modules that do carry data are not directly readable, because the whole symbol has been passed through a masking operation before printing. A black square in a QR code may encode a 1 or a 0 depending on which mask was applied — and we will come back to that, because it is the strangest part of the format.
The layering runs: modules to bits, bits gathered into codewords of 8 bits each, and error correction operating on codewords. Almost everything interesting happens at the codeword level, and almost everything people say about QR codes is said at the module level, which is why so much of it is loose.
Sizes are standardized into 40 versions — and “version” here means grid size, not revision, which is the specification’s least helpful word choice. The side length in modules is 17 + (4 × version), so version 1 is 21×21 and version 40 is 177×177. Codes of version 7 and above carry an additional block recording their own version; smaller ones don’t need it, because the scanner can simply count the grid. Around the whole thing there must be a quiet zone of at least 4 modules of blank space, mandated by the international standard.3
Getting data in
QR codes have four encoding modes, and the choice matters more than you would expect.
Numeric mode costs 3.33 bits per digit. Alphanumeric mode costs 5.5 bits per character, and covers digits, uppercase letters, and a handful of punctuation marks — no lowercase. Byte mode costs 8 bits per character. Kanji mode costs 13, and it is worth pausing on the fact that kanji is a first-class encoding mode in the specification rather than an extension, which tells you exactly who the format was built for.
The practical consequence turns up constantly and almost nobody notices it. A URL written in uppercase can use alphanumeric mode at 5.5 bits per character. Add a single lowercase letter and the whole thing drops to byte mode at 8, and the code grows to accommodate it. This is why the URLs printed under QR codes on older signage are so often shouting at you in capitals.
Layered on top is the error correction level, chosen at encoding time: L, M, Q, or H, corresponding to roughly 7%, 15%, 25% and 30% recovery. Higher levels cost capacity, which means more modules for the same data — so either a bigger code or smaller modules.
At maximum capacity — version 40, level L — the format holds about 7,089 digits, 4,296 alphanumeric characters, 2,953 bytes, or 1,817 kanji. Against a barcode’s 20 characters, this is the whole point.
Redundancy that isn’t a copy
The error correction is not specific to QR codes. It is Reed–Solomon coding, published in 1960 by Irving Reed and Gustav Solomon at MIT’s Lincoln Laboratory.4 It is one of the most quietly consequential pieces of mathematics of the twentieth century. It is on compact discs and DVDs. It is in deep-space telemetry, including the Voyager spacecraft. Readers of my essay on GPS will recognize both the laboratory and the era; the same handful of rooms in the early 1960s produced a startling amount of the infrastructure we now take for granted.
The mechanism is easier to feel than to formalize. Suppose your message is a short list of numbers. Treat those numbers as the coefficients of a polynomial, and then evaluate that polynomial at more points than you strictly need — if two points determine a line, evaluate at six. Transmit all six. If two of them arrive corrupted, the remaining four still determine the same line, and you can refit the curve and read the original coefficients back off it. The redundancy is not a copy of the data. It is additional views of the same underlying object.
Reed–Solomon for QR codes operates in GF(2⁸) — a finite field with 256 elements, which is to say exactly the number of values a byte can take. That is not a coincidence, and it is why the codeword is 8 bits. The arithmetic and the data unit were chosen to fit each other.
One thing it is not, despite looking like it: error correction is not encryption. The two have nothing to do with each other. Redundancy protects against damage, not against readers, and the payload of every QR code is plaintext to anyone who scans it.
This is also the point at which to correct the most-repeated claim about QR codes. You will read everywhere that you can destroy 30% of a QR code and it will still scan. The figure is real but it is not a percentage of area. It is the proportion of codewords that can be recovered at level H. Area and codewords are not interchangeable, because damage to a finder pattern or a timing pattern is not recoverable at all — those carry no error protection, and if you obliterate one the code is simply gone, however much of the rest survives.
Erasures, and why 30% holds up anyway
Here is the detail that almost nobody outside the field knows, and it is the one that makes the 30% figure behave better in practice than it has any right to.
Reed–Solomon can correct two different kinds of damage. An error is a corrupted symbol at an unknown position: the decoder knows something is wrong somewhere but not where. An erasure is a corrupted symbol at a known position: the decoder knows precisely which symbol is missing.
The cost is different. Correcting an error consumes two correction symbols, because the decoder must first locate the damage and then repair it. Correcting an erasure consumes one, because the locating has already been done. Erasures are, in the most literal sense, twice as cheap.
And a QR scanner almost always knows where its failures are. It has the geometry of the grid from the finder patterns; it knows there is supposed to be a module at a particular coordinate; and when it looks there and finds a smear of coffee or the edge of a sticker or nothing at all, it does not record a guess, it records a gap. Real-world damage to a QR code is overwhelmingly erasure rather than error, so the correction budget goes roughly twice as far as the raw numbers suggest.
This is also where the logo in the middle of a corporate QR code comes from. The logo is not encoded into anything. It is simply printed over the modules, obliterating them, and the decoder treats the whole blank region as erasures and rebuilds what was underneath. Which is why the rules for doing it are what they are: use level H, keep the logo under roughly a quarter of the module area, and never let it touch a finder or timing pattern — because those are the parts no amount of redundancy can reconstruct.
One more mechanism completes the picture. The encoder interleaves the codewords, distributing them across the symbol rather than laying them down in order. A coffee ring therefore damages a small piece of many codewords instead of destroying a few outright, and Reed–Solomon handles a broad shallow wound far better than a narrow deep one. The damage is deliberately spread before it happens.
The eight drafts
Now the strangest part, and the one that changed how I look at these things.
Suppose the data you are encoding happens to produce a large blank region, or a long run of identical modules, or — worst of all — a pattern in the middle of the grid that looks like a finder pattern. The code would be technically valid, but practically unreadable. The specification cannot forbid this, because it cannot control what data you want to encode.
So the format cheats. Eight masking patterns are defined, each one a simple formula on the row and column number: mask 0 inverts every module where (row + column) is even, mask 1 inverts every module in an even row, and so on. The encoder generates all 8 variants of your code — each one the same data wearing a different mask — and scores each against four penalty rules: runs of 5 or more identical modules in a row or column, 2×2 blocks of the same color, sequences that resemble finder patterns, and an overall imbalance of dark to light. The variant with the lowest penalty score — the one the rules judge least likely to give a scanner trouble — wins and is the one that gets printed. Three bits in the format information record which mask was used, so the scanner can undo it.
Every QR code you have ever seen had 7 siblings, generated and discarded moments before it was made.
The format information holding that mask number is itself worth a moment. It is 15 bits, protected by its own error-correcting code, and then — before being written into the symbol — it is XORed against the fixed pattern 101010000010010. There is no cryptographic purpose to this. That XOR exists for one reason: to guarantee that the format bits can never, for any legal combination of inputs, come out looking like a finder pattern.
That is the third time in this essay that the specification has spent real effort on the same worry. Six months of photographing newspapers to find a sequence that print does not produce. A penalty rule against accidental finder lookalikes in the data region. A fixed XOR mask so the format bits cannot imitate one either. For a format built to be read at speed by cheap hardware on a factory floor, the expensive failure was never a code that could not be read. It was a code read as something it was not.
Why it spread
Denso Wave holds the patent. It was granted in March 1994, and the company has never enforced it against anyone using the format as specified.
The company published the specification and declared from the outset that it would not exercise its rights, on the grounds that the code should be usable by as many people as possible.5 The normative document, ISO/IEC 18004, will still cost you 227 Swiss francs from ISO (about US$275) — but that is the price of the paper, not of the right to use it, and there is enough on Denso’s own site to build a working encoder from.
The reasoning was not altruism, or not only altruism. A tracking format is worthless until everyone has adopted it, and charging for it guarantees that they will not.
What Denso did keep is instructive. The trademark on the name is enforced, which is why adopters were asked to print an attribution line. The company sells the industrial scanners. And it holds proprietary variants built on top of the open base — SQRC, which restricts who can read part of the payload, and FrameQR, which allows artwork inside the symbol. Denso gave away the format and monetized everything adjacent to it. Thirty-two years on, that looks less like generosity than like the best business decision anyone at the company ever made.
The threat that wasn’t in the brief
There is one thing the specification has nothing to say about, and you can find it by asking a question the 1994 design never had to answer: who made this code?
Not one bit of the format is reserved for that. There is no signature, no issuer field, no provision for authentication of any kind. A QR code asserts a destination and offers no evidence about its own provenance, and the person holding the phone cannot inspect it, because the payload is not human-readable. A URL printed on a poster can be read and doubted. The square next to it cannot.
In a Denso plant this was not a gap. The only person printing your codes was you. The threat model was oil, tearing, glare, bad angles, and ambiguity with newsprint, and against every one of those the format is superbly well defended. Deception simply was not on the list, because deception requires a hostile author, and in a closed industrial system there is no such thing.
Then the format escaped. Camera phones arrived in Japan in 2002, Apple put a decoder in the iOS camera in 2017, and the pandemic put a code on every restaurant table in the world, at which point scanning an unfamiliar square became a thing that ordinary people do several times a week without hesitating.
What followed has a name now: quishing, phishing by QR code. The attacks are not sophisticated and they do not need to be. A code in an email, generated by the attacker, that slips past filters trained to inspect links because it is an image rather than a link. A sticker on a parking meter, laid over the legitimate code underneath.6 A field study at a German research campus tested this directly. Posters advertised a survey on inflation, from an institution that did not exist. Scan rates were low — 51 scans in two weeks on a campus of 25,000. But the professionally designed poster, offering a prize, drew nearly three times as many as the plain one. The codes were identical. Only the packaging differed, and the packaging is the only thing a person can judge.7
It is tempting to call this a flaw, but it isn’t one. Hara built exactly what he was asked to build, and he built it so well that it outlived its own assumptions by three decades and several orders of magnitude of scale. The code defends brilliantly against a hostile environment. It has nothing to say about a hostile author, because in 1994 there weren’t any.
The next time one resolves in under a second, at a bad angle, through a glare, off a scuffed sticker: that is a factory tool, still doing its job perfectly, in a world it was never told about.
Denso Wave publishes its own history of the code. (Denso spun the division off as Denso Wave in 2001; sources referring to “Denso Wave in 1994” are using the later name for the earlier company.)
From Denso’s interview with Hara marking the code’s 30th anniversary, “Believing in a Faint Light”.
ISO/IEC 18004. The quiet zone is the most commonly violated requirement in the format — a designer crops to the edge of the pattern and the code becomes unreliable for reasons nobody in the room can diagnose.
I. S. Reed and G. Solomon, “Polynomial Codes Over Certain Finite Fields”, Journal of the Society for Industrial and Applied Mathematics, 1960.
Several online accounts place the non-enforcement decision around 1999 rather than at release. None of the ones I found cites a source for it, and Denso Wave’s own history of the code says the opposite — that the policy was in place from the beginning of development, honoring the developers’ intent that the code be usable by as many people as possible. I suspect, though I can’t demonstrate, that the later date is an artifact of the standards timeline: QR became an AIM standard in 1997, a JIS standard in 1999, and an ISO standard in 2000, and 1999 is the kind of date that attaches itself to a story about a format being opened up. Where a company’s own account and an uncited secondary one disagree about that company’s internal decision, I’ll take the company’s.
Researchers have also demonstrated altering an existing code at the module level so that it still decodes, but to a different destination — see Kieseberg et al., “Malicious Pixels Using QR Codes as Attack Vector”, 2012, and Dabrowski et al., “QR Inception: Barcode-in-Barcode Attacks”, 2014. These are real but largely academic; the field attacks are stickers and email attachments, because they work and require nothing.
Geisler, Pöhn and Hommel, “Hooked: A Real-World Study on QR Code Phishing,” arXiv:2407.16230. The authors stopped short of capturing credentials, so the study measures willingness to scan rather than susceptibility to being phished, and they note the participation rate was under 1%.







