QR Code

The QR encoder on its own: text in, a grid of dark and light modules out, with no markup and no rendering. QrEncoder is the whole of ISO/IEC 18004 — every version from 1 to 40, all four error correction levels, three encoding modes, Reed-Solomon over GF(256) and the eight mask patterns scored by the specification's own penalty rules.

Encode and Inspect

The encoder chooses three things on its own: the most compact mode the whole string fits, the smallest version that holds the payload at the requested level, and the mask that scores best under the four penalty rules. All of it is deterministic — the same text and level always produce the same grid. Type below and watch the version and the mode move.

One Mode for the Whole String

Numeric packs about 3.33 bits a character, alphanumeric about 5.5, and byte a full 8 per UTF-8 byte. One mode is chosen for the whole string rather than splitting it into mixed-mode segments, so a string that is mostly digits with one lower-case letter in it encodes as bytes. That can cost a version against an optimal split; the simpler rule is easier to reason about and the difference only shows on long, mixed strings.

Walking the Grid, Quiet Zone Included

The grid stops at the code itself — the quiet zone is the caller's job, and four modules on every side is the specified minimum. The indexer returns false for any position outside the grid, so a renderer can walk past the edges with no bounds checks of its own. That is what makes this loop two lines rather than six.

Ask Before Encoding

GetCapacity reports the largest number of characters a version holds at a given level and mode — and in Byte mode it counts UTF-8 bytes, not characters. Use it to check a value will fit rather than catching the exception afterwards.

Encode Throws Rather Than Returning Null

Past the version 40 capacity, Encode throws an ArgumentException whose message names the capacity needed and the capacity available. A Blazor component must catch it and render a message instead — an unhandled exception on Blazor Server takes the circuit down. BbQrCode already does this.

Verification

Every module of every test vector matches matrices produced by segno — which turned out to pad a spurious byte when the bit stream already ends on a codeword boundary, so the reference had that one line corrected. Then 161 codes spanning versions 1 to 40 were rasterised and decoded back to their original text.