Skip to content
UseQR
ESC

Jump to

MOVEOPEN50 places

Reference tables

QR mask pattern reference: formulas, penalties, format bits

Eight mask patterns, numbered 0 to 7, decide which data modules are inverted; mask 0 inverts where (row + column) mod 2 equals 0. The encoder draws all eight, scores each against penalty rules N1–N4 with weights 3, 3, 40 and 10, and keeps the mask with the lowest total.

View as MarkdownPaste this page into any AI assistant. It is plain, portable Markdown.

The eight mask formulas

A mask inverts every data module where its condition is true. i is the row and j the column, both counted from 0 at the top-left. Function patterns (finders, timing, alignment, format info) are never masked.

Mask Condition (invert where true) Visual effect
0 (i + j) mod 2 == 0 Checkerboard
1 i mod 2 == 0 Horizontal stripes, every other row
2 j mod 3 == 0 Vertical stripes, every third column
3 (i + j) mod 3 == 0 Diagonal stripes
4 (⌊i/2⌋ + ⌊j/3⌋) mod 2 == 0 Coarse checkerboard of 2 × 3 blocks
5 (i × j) mod 2 + (i × j) mod 3 == 0 Grid of crossing lines
6 ((i × j) mod 2 + (i × j) mod 3) mod 2 == 0 Thickened lattice
7 ((i + j) mod 2 + (i × j) mod 3) mod 2 == 0 Alternating diagonal blocks

These are exact: verified against the working encoder behind UseQR, and part of how every QR code is generated.

The penalty rules

The encoder renders the symbol eight times, scores each candidate, and keeps the lowest penalty score.

Rule Detects Penalty
N1 A run of ≥ 5 same-colour modules in a row or column 3 + (run length − 5) per run
N2 Each 2 × 2 block of one colour (overlapping blocks all count) 3 per block
N3 The finder-like ratio 1:1:3:1:1 (dark-light-dark-dark-dark-light-dark) with 4 light modules on one side 40 per occurrence
N4 Overall darkness away from 50% 10 per 5% step of deviation

N3's weight of 40 dwarfs the others because a false 1:1:3:1:1 run can make a scanner hunt for a fourth finder pattern that does not exist.

One honest footnote: several widely used encoders (including the library UseQR builds on) score N3 on the seven-module run alone, without checking the four light modules the standard requires beside it. Both are valid symbols; they just sometimes pick different masks, which is one reason two generators can produce different codes for identical input.

Format information bits

The chosen mask is announced in the 15-bit format information: 2 bits of error-correction level, 3 bits of mask number, 10 bits of BCH error correction, all XORed with the fixed pattern 101010000010010. The level indicator is counterintuitive: L = 01, M = 00, Q = 11, H = 10.

All 32 possible format strings (computed from the BCH(15,5) generator 10100110111):

Mask Level L Level M Level Q Level H
0 111011111000100 101010000010010 011010101011111 001011010001001
1 111001011110011 101000100100101 011000001101000 001001110111110
2 111110110101010 101111001111100 011111100110001 001110011100111
3 111100010011101 101101101001011 011101000000110 001100111010000
4 110011000101111 100010111111001 010010010110100 000011101100010
5 110001100011000 100000011001110 010000110000011 000001001010101
6 110110001000001 100111110010111 010111011011010 000110100001100
7 110100101110110 100101010100000 010101111101101 000100000111011

A useful side effect of the XOR mask: level M with mask 0 encodes as 101010000010010 (the XOR pattern itself), so an all-zero format field can never appear in a valid symbol.

Checking a real code

You cannot choose the mask when generating (the encoder must pick the lowest penalty), but you can read which one was used: decode any code and inspect the format bits, or scan it and compare two generators' output for the same payload.

FAQ

What are the 8 mask patterns in a QR code?

Eight inversion conditions applied to data modules: checkerboard, row stripes, column stripes, diagonal stripes, a 2 × 3 block checkerboard, and three lattice patterns built from (i × j) mod 2 and mod 3 terms.

How is the best mask pattern chosen?

The encoder renders all eight candidates and scores each with four penalty rules: long runs, 2 × 2 blocks, false finder patterns and dark/light imbalance, weighted 3, 3, 40 and 10. The lowest total score wins.

Can I pick the mask pattern myself?

The specification says the encoder should evaluate all eight and take the lowest penalty. A forced mask still decodes (the mask number is stored in the format information), but it may scan less reliably.

Why do two generators put different patterns on the same data?

Usually a different mask choice. Implementations disagree slightly on penalty rule N3's exact reading, and a one-point difference flips the winner. Both outputs decode to identical data.

Try it: free, no signup