# QR code bit stream walkthrough, from text to modules

> A QR bit stream is built as mode indicator, character count, encoded data, a 4-bit terminator, then pad bytes 0xEC and 0x11 to fill capacity. Codewords are split into blocks, extended with Reed–Solomon check codewords, interleaved, placed in a zig-zag from the bottom-right corner, masked, and topped with format information.

Source: https://useqr.app/docs/spec/qr-code-bit-stream-walkthrough · Last reviewed 2026-08-21 · UseQR is free forever, no signup.

---

## The pipeline at a glance

```
segments → terminator → pad bytes → blocks → RS codewords → interleave
        → remainder bits → zig-zag placement → mask → format/version info
```

Each stage is mechanical; run them in order and any two correct encoders produce the same
codewords for the same input, version, and
[error-correction level](/glossary/error-correction-level). (Divergence enters only at
[mask selection](/docs/spec/mask-selection-penalty-scores).)

## Stage 1: the data bit stream

Each segment is a 4-bit [mode indicator](/docs/spec/data-encoding-modes), a character
count field (8–16 bits wide depending on mode and version), then the encoded characters.
After the last segment come the closing formalities:

1. **Terminator**, up to four `0` bits (fewer if capacity runs out exactly).
2. **Pad to a byte boundary** with `0`s.
3. **Pad bytes**, the alternating pair `11101100 00010001` (**0xEC 0x11**) repeated
   until the version's data capacity is exactly full. The values are not arbitrary:
   they are balanced bit patterns chosen so padding never creates the uniform areas the
   [penalty rules](/docs/spec/mask-selection-penalty-scores) exist to punish. Spot
   `EC 11 EC 11` in a hex dump and you are looking at a QR code's slack space.

## Stage 2: codewords, blocks and error correction

The stream is cut into 8-bit [codewords](/glossary/codeword) and split into the block
structure the standard fixes for this version and level. Each block gains its
[Reed–Solomon check codewords](/docs/spec/reed-solomon-error-correction), and the blocks
are then [interleaved](/docs/spec/error-correction-block-interleaving), data codewords
round-robin across blocks, then check codewords the same way.

A final oddity: some versions' module counts are not a multiple of 8, so **remainder
bits** (always `0`) top up the stream: 7 of them for versions 2–6, 3 or 4 for various
versions from 14 to 34, none elsewhere.

## Stage 3: placement: the zig-zag

Function patterns claim their territory first; data fills what is left, in a pattern best
described as reading a book backwards:

- Placement works in **vertical column pairs, two modules wide**, starting at the
  **bottom-right corner**.
- The first pair fills **upward** (within each two-module row of the pair, right cell
  then left cell), until it hits the top, then the next pair to the left fills
  **downward**, alternating all the way across.
- Any cell claimed by a function pattern or reserved field is **skipped**, the sequence
  flowing around it; and the entire single column of the vertical
  [timing pattern](/docs/spec/timing-patterns) (column 6) is stepped over, keeping pairs
  aligned either side of it.

The most significant bit of the first codeword lands in the bottom-right corner cell.

## Stage 4: mask, then metadata

The placed data region is XORed with the winning
[mask pattern](/docs/spec/mask-patterns-0-to-7). Finally the 15-bit
[format information](/docs/spec/format-information) (level + mask, BCH-protected, XORed
with `101010000010010`) is written twice, and from version 7 the 18-bit
[version information](/docs/spec/version-information) twice more. The symbol is complete.

To watch every stage with real numbers, follow the worked example in
[encode HELLO WORLD by hand](/docs/spec/encode-hello-world-by-hand), or generate any
payload and [decode it back](/validate) to confirm the pipeline round-trips.

## FAQ

### What are the pad bytes 0xEC and 0x11 in a QR code?
Filler appended after the terminator to bring the data stream exactly to the version's capacity. They alternate (11101100, 00010001), and their balanced bit patterns avoid creating large uniform areas that would scan poorly.

### How is data physically placed in a QR code?
In two-module-wide column pairs, starting at the bottom-right corner, filling upward then downward alternately across the symbol, skipping function patterns and stepping over the vertical timing column entirely.

### What are remainder bits?
Zero bits appended after the final interleaved codeword because some versions have a few more data modules than a whole number of codewords fills: 7 bits for versions 2–6, 3 or 4 for several mid-range versions, none for the rest.

### What order do the encoding stages run in?
Segments with mode and count headers, terminator, byte padding, pad bytes, block split, Reed–Solomon check codewords, interleaving, remainder bits, zig-zag placement, masking, and finally the format and version information fields.

## Try it

- https://useqr.app/url
- https://useqr.app/validate
- https://useqr.app/scan
