QR Codes

QR codes are a two-dimensional equivalent of barcodes: a graphical encoding of information, which in practice means a string of about 4000 alpha-numeric characters (upper-case only) or a little less than 3000 arbitrary bytes.

So, how then are QR codes able to perform magic, such as automatically opening web pages, or sending text messages, or even dealing bitcoin? The answer is: they can’t.

Let’s try to understand what’s going on.

What are QR Codes?

QR Codes were developed in the 1990s, by the Japanese company Denso Wave (a Toyota subsidiary). As opposed to regular barcodes, QR Codes are two-dimensional, making for very high information density and redundancy. Redundancy is variable between 7% and 30% — the latter means that even if about one third of the QR Code is destroyed or obscured, all of the encoded information can still be recovered! The desired amount of redundancy must be specified when creating a QR Code; codes with higher redundancy are larger (they have more points). Overall, the number of points in a QR Code is not fixed: it depends on the length of the message and the amount of redundancy.

Text Low Redundancy High Redundancy
I am QR Code QR Code
I am the walrus QR Code QR Code

QR Code “Actions”

It is important to keep in mind that a QR Code simply decodes to an alphanumeric string, or, at best, to a sequence of bytes. There is absolutely no magic here, and there are no “secret” keywords one could include to trigger some action on the reading device.

Instead, all the “magic” is in the reader. (In practice, this is most likely the camera app on a cell phone; before QR functionality was included in most camera apps, separate QR Code readers were common.) The reader decodes the string represented by the QR Code, and then applies some heuristics, based on the content, in order to decide what to do. (Again, in practice, the app may give the user some choices of which action to take, or, with appropriate permissions, take the action automatically.) In other words, if the content looks like a URL, the app may suggest to open the URL in a browser. And so on.

Again: the magic is not in the QR Code, but in the reader. QR Code generators, which usually offer a variety of “formats” (such as text, URL, SMS, email, and so on) tend to obscure this fact. Nevertheless, for a URL like www.janert.me or https://www.janert.me, exactly the same QR code may be generated, whether encoded as “text” or as “URL”.

Or not. QR Code generators frequently manipulate their input. For example, they may add a protocol (such as https://) when encoding a “URL”, if they believe it is missing. And different generators behave differently.

Some formats have been developed to indicate other types of content (emails, SMS, VCards, …). QR Code generators will typically use such formats when instructed to create a QR Code for a VCard, for example. However, none of these formats are formal standards, and there is often some ambiguity in how to apply them. And reading devices are anyway free to interpret the encoded message more or less strictly.

The most important take-away here is that there is no way to encode a “command” in a QR Code that will force-trigger some action in the reader. There are some conventions to help readers interpret messages appropriately, but ultimately, a QR Code is just a “bag of bytes”. It’s up to the reader to decide whether to take any action, based on the decoded message.

Dynamic QR Codes, Password Protection, and Multi-Media

One will also find references to “dynamic QR Codes” (that supposedly can be “updated after they have been generated”), password-protected QR Codes, and QR Codes that encode entire image galleries. How should any of this be possible with a fixed string of less than 3000 bytes?

The answer is that it isn’t. All of these applications work by encoding a unique but fixed URL in a QR Code. When scanned, the QR Code will take the user to the content at that URL. Of course, the content hosted at that location may change, may be password protected, or may consists of a gallery of images or other multi-media files. The key point is that none of this is encoded in the QR Code itself; instead, it is hosted on a webserver. (Which is also why all these solutions require an account with the QR Code generator, whereas static content such as VCards can usually be generated for free.)

Most creative solutions around QR Codes seem to revolve around this idea: direct the user to a website, and then take it from there.

Tools and Resources


The first place to start is probably the Wikipedia page on QR Codes.

Official documentation on QR Codes is a bit scattered and can be hard to come by. The Denso Wave company still holds a number of applicable patents. They maintain a website dedicated to the topic.

The latest versions of the QR Code spec are ISO standards, which are not freely available.

Many of the “formats” for encoding different types of payloads where first developed by NTT DoCoMo. A comprehensive overview, which also highlights some additional practical concerns and opportunities can be found in the documentation for the ZXing project. But also see the “Format” section of the Qrcode Library documentation.


Two websites that provide useful QR Code generators are www.qr-code-generator.com and www.qrcode-monkey.com.

On Linux, the qrencode utility, which is part of the libqrencode library, can generate QR Codes. There is also a convenient Qt GUI frontend, called qtqr, which unfortunately is no longer being maintained.

To decode QR Codes on Linux (and to confirm what a QR Code generator has really encoded), the zbarimg utility is useful; it is part of the zbar-tools package.