Did you know that most QR codes have millions of equivalent permutations?

Having options gives us the freedom to curate patterns that match an aesthetic or fulfil a design constraint.

Generating Permutations


(1) Message variation

HTTPS://VIMBRANDT.COM
HtTpS://ViMbRaNdT.cOm/
hTtPs://vImBrAnDt.CoM

For web links, we can safely permute the casing of the hostname and the protocol, as URLs are explicitly case-insensitive for these regions. If someone inspects the contents of the QR Code, crazy caps can look a little ugly. The ideal choice depends on the project.

Every QR Code payload type (phone, email, geo, etc) has different permutation options based on the corresponding spec.

The larger the QR Code has to be, the less relevant all of this is. In general, custom designs work best on relatively-small QR codes (99% of cases).

For serious projects, it's worth creating a custom permutation generator in tandem with the website you're targeting. For example, you could iterate over a fixed vocabulary of subdomains and append a custom numeric query for even more control for even more control.


(2) Encoding Strategy

Once we have a data payload string like HTTPs://VIMBRANDT.COM/?n=67, we have to construct valid QR binary codewords.

The QR Code format defines 4 "Modes" to encode text: Byte, Alpha, Numeric, Kanji

For every character, we can test which modes are valid. Modes with larger charsets are less efficient, and every mode switch incurs a fixed cost.

H
T
T
P
s
:
/
/
V
I
M
B
R
A
N
D
T
.
C
O
M
/
?
n
=
6
7

Eventually, we're constrained by the size of the QR code. For a given version and ecl, we can calculate the most efficient strategy and the amount of leftover padding bits. With more padding, we can fit more encoding-level permutations.


(3) QR Code Masks

QR Codes have 8 mask patterns built-in. Masks are XOR'ed with the raw data codewords to produce the final grid. According to the spec, the grid with the lowest penalty score should be used, but practically, all 8 will scan properly.


Pattern Selection

If we have a search space of QR codes, we can sort them based on aesthetic scores. For example:

Number of Pixels number of cells that are "on"
149
266
Number of Dots number of cells with no adjacent neighbors
0
68
Number of big squares number of 4x4 "on" regions
0
33

These QRs were found on a search over all possible encodings and masks of HTTPS://VIMBRANDT.COM (only permuting over options from (2) and (3)).

This single search yieled 24 million QRs to grade and took 15 minutes. Only 1 of those 24 million had 0 dots. You can start to imagine that certain patterns yield themselves to certain aesthetics.

For a larger project, it would be possible to iterate over billions of possible QRs, saving all variants that meet some requirement.


For brevity, I'll stop here and skip most of my implementation details. But, it should be clear that designing aesthetic QR codes involves more than just applying styles to pixel grids.