A Code 128 barcode drawn as line art, where a lookup table and a checksum decide every bar.
A barcode is already line art
Nobody designed the pattern on a supermarket label. It is what falls out when a
string is pushed through Code 128, a symbology from 1981 whose whole job is to
turn characters into bars that a scanner can read back. The widths are not
chosen; they are the arithmetic made visible.
That makes it a generative piece with an unusual property: the composition is
entirely determined, and yet nothing about it is decorative by intent. Feed it a
different string and you get a different picture, with no parameter to tune and
no random seed to draw. The decisions left are colour, scale, and how the band
is placed — rotated, repeated, cropped, or kept as the measure that drains.
The module
The atom is the module — one column, BarWidth pixels across. A bar is a run
of adjacent dark modules; a space is a run of light ones. Every data symbol in
Code 128 is exactly eleven modules wide, split into three bars and three spaces,
each between one and four modules. Bars therefore come in four widths, and never
a fifth.
Because the symbol width is fixed, the width of the finished code is known before
any of it is drawn:
modules = 11 × (1 start + n characters + 1 check) + 13 stop
= 11 × (n + 2) + 13
The measure, drawn as one faint rule per module boundary. Nothing has been
encoded. The lattice is exactly the footprint the code will fill, and it drains
from the left as each group of modules is committed.
Start
Code 128 has three code sets, and the first symbol says which one is in force.
This piece uses set B — mixed case, digits and punctuation — whose start symbol
is 11010000100, symbol value 103.
That value does double duty. It is the first term of the checksum as well as the
signal to the scanner, which is why the sum below begins at 103 rather than at
zero.
Eleven modules placed. Read the run lengths left to right — a two-module bar, a
one-module space, a one-module bar, a four-module space, a one-module bar, a
two-module space — and you have read the symbol. There is nothing else in it.
Payload
Each character is looked up in a table of ninety-six entries — the whole of code
set B — and each returns an eleven-bit string and a numeric value. TextToInput
concatenates the bit strings; the values are kept back for the checksum.
"6" → 11001110100 value 22
"4" → 11001001110 value 20
"0" → 10011101100 value 16
" " → 11011001100 value 0
"-" → 10011011100 value 13
There is no escape hatch. A character outside the table throws rather than
substituting something plausible, because a barcode that encodes an
approximation of the string is not a barcode.
The body of the code. This is the only stage whose length depends on the input —
every other group is a fixed eleven or thirteen modules however long the payload —
which is why the renderings beside it end in different places.
Check
One symbol is appended before the terminator: the modulo-103 check symbol. Each
data symbol contributes its value times its one-based position, the start symbol
contributes 103 at weight one, and the total is reduced modulo 103.
check = (103 + Σ (i + 1) × value(textᵢ)) mod 103
For the lead payload 640509 - 040147 that sum is 2049, and 2049 mod 103 is 92 —
the value belonging to FS, whose bit pattern 10101111000 is what actually gets
drawn. The check symbol is looked up by value, not by character, so the symbol
that lands here is usually one with no printable meaning at all.
Eleven more modules, indistinguishable by eye from the payload and carrying no
part of the message. Their only job is to make every preceding symbol
falsifiable.
Stop
The terminator is thirteen modules, 1100011101011: a normal six-element symbol
with a two-module bar bolted on the end so that a scanner reading the code
backwards can still tell where it stopped.
The lattice is gone, because every module now belongs to a symbol. The picture is
finished and, held under a scanner, still reads.
Geometry
The drawing is as plain as the encoding is strict. Module k occupies the
horizontal interval [LeftMargin + k·BarWidth, LeftMargin + (k+1)·BarWidth),
and every bar spans the same vertical band, BarHeight tall, centred five
pixels above the middle of the canvas. Three of those facts are knobs rather
than constants — LeftMargin and BarTop can be pinned, and the whole
composition can be rotated about the canvas centre — because the variants below
push the same five moves into compositions the turtle never attempted.
Two nuances are worth naming, because both are inherited rather than designed:
The margin is part of the composition. The default left margin is 80 pixels —
the turtle’s starting position in the original sketch. Every preset sets its own,
because the margin decides how the band sits in the frame: the lead spans the
canvas edge to edge at zero, the shorter payloads centre themselves, blinds
keeps its stripes nearly flush, and a negative one crops the code at the left
edge so the frame holds a section of the stream instead of its beginning.
Five pixels of history. The band every bar shares hangs five pixels above the
canvas midline — the offset at which the original turtle started each pen stroke.
It is kept as a constant in the geometry (BarTop), not as cursor state, and it
is the only trace the turtle leaves: the bars themselves are plain rectangles,
one per run of adjacent modules, positioned by arithmetic.
The variants
Seven renderings share the algorithm; what changes between them is the
composition around it. Each turns a knob the original left at zero, so the set
reads as one idea seen from different distances and angles rather than one image
in different inks — and every variant stages the same five moves, its own
geometry being assembled measure by measure. An eighth plate then presents the
canonical rendering hung on a gallery wall.
| Rendering | Payload | Structure | Ink |
|---|
| Cyan Scan | 640509 - 040147 | the canonical band — six-pixel modules spanning the canvas | #00FFFF on #000000 |
| Registration | AGENT 47 | paper and ink, with the module lattice left standing | #1B1B1F on #F5F1E8 |
| Afterimage | ICA 2024 | six copies stacked, each fading one step further | #FF00FF on #050508 |
| Blinds | ICA 2024 | bars pinned to bleed top and bottom, wide canvas | #5D84F1 on #0D1117 |
| Checked | AGENT 47 | check and stop symbols tinted against the payload | #ECE9E2 + #E5484D on #141418 |
| Ladder | 640509 - 040147 | the same code standing on end, rotated 90°, full height | #FFB000 on #0B0B0E |
| Close-up | 640509 - 040147 | twelve-pixel modules, the stream outgrowing the frame | #8A6BFF on #0A0A14 |
| Hung | 640509 - 040147 | the canonical band hanging on a wall, matted and framed | cyan on black, on ivory and charcoal |
Registration inverts the palette and keeps the measure. The background is
paper, the bars are ink, and the lattice the progression drains is drawn
permanently — ShowLattice — so the finished code keeps its own working lines,
a proof sheet that was never cut.
Afterimage repeats the band. Repeat draws the same code six times, ninety
pixels apart, each copy forty alpha steps fainter than the last: a scan line
caught falling, or a monitor mid-refresh. The first copy is the committed one;
the rest are its afterimages.
Blinds pins the band to the top edge and lets the bars run the full height
of a wide canvas, so a short payload becomes floor-to-ceiling stripes — the
same four bar widths, at the scale of a wall.
Checked colours the falsifiable part. The check symbol and the stop symbol —
the two groups a scanner uses to refute a misread, indistinguishable by eye in
the lead — are drawn in Accent while the payload stays neutral. The stage that
commits them is the stage the colour arrives.
Ladder rotates the whole composition 90°: the same 200 modules standing on
end, the orientation scanners call a ladder. The five pixels of history go
sideways with it.
Close-up enlarges the module and pushes the stream off the left edge with a
negative LeftMargin, so the frame holds a section of the code rather than its
beginning — bars cut mid-run at both ends, the stop symbol out of the picture
entirely.
The presentation
One plate in the gallery is the piece hung. MuseumFrame — the presentation
layer from SkiaSharp.Extensions — hangs the canonical band the way a gallery
would: a wall, a mat with an opening, the artwork fitted into it, and a frame,
with every band sized as a fraction of the shorter canvas side. The frame knows
nothing about barcodes and the barcode knows nothing about being framed: the
inner piece is drawn at its own 1200×1200 and fitted into the opening, so the
framing never touches the generative geometry and could present any of the
renderings above without change.
Determinism
There is no randomness here to control. No generator is seeded because none is
used: the symbol table is a constant, the checksum is a formula, and the geometry
is arithmetic on the initialiser values. The same source produces the same pixels
on any machine.
One detail was checked rather than assumed. The check symbol is found by scanning
the symbol table for the entry whose value matches, and dictionary iteration order
is formally unspecified — but every value in the table is unique, so exactly one
entry can match and the order cannot matter.
Origin
Ported from the Turtletoy sketch Agent 47,
itself forked from What time is it? by bap. CC BY-NC-SA 4.0. The payload
640509 - 040147 is the barcode tattooed on the back of Agent 47’s head in the
Hitman series.