LZW

LZW compresses by replacing repeated phrases with numbers, which would be unremarkable except that the table of phrases is never transmitted. The decoder starts with nothing but the alphabet and reconstructs the encoder’s dictionary from the codes as they arrive, always exactly one entry behind. Being one behind is survivable in every case but one, where the encoder uses a code in the same step that creates it — and the decoder can still work out what it must have been. Everything below is encoded and decoded as you type.

A dictionary that is never sent, because both ends build the same one

1 A string with repeats, and a dictionary holding nothing but the alphabet

A string with repeats, and a dictionary holding nothing but its alphabet.

alphabet
B E N O R T
codes 0 upward
0=B 1=E 2=N 3=O 4=R 5=T
first free code
6

2 Encode: emit the code for the longest phrase you have, then add the one you just proved exists

Encode. Emit the code for the longest phrase already known, then add the phrase you just proved exists — one character longer, and seen for the first time.

stepemitsforadds
15TTO = 6
23OOB = 7
30BBE = 8
41EEO = 9
53OOR = 10
64RRN = 11
72NNO = 12
83OOT = 13
95TTT = 14
106TOTOB = 15
118BEBEO = 16
1210ORORT = 17
1315TOBTOBE = 18
149EOEOR = 19

16 code(s) out of 24 character(s): 5, 3, 0, 1, 3, 4, 2, 3, 5, 6, 8, 10, 15, 9, 11, 13 (first 14 steps shown)

3 Decode with no dictionary sent, rebuilding the same table from the codes alone

Decode. The only things that crossed are the codes above and the alphabet; the table below is rebuilt, not received.

codemeansaddshow
5T— (nothing yet)read from the table
3OTO = 6read from the table
0BOB = 7read from the table
1EBE = 8read from the table
3OEO = 9read from the table
4ROR = 10read from the table
2NRN = 11read from the table
3ONO = 12read from the table
5TOT = 13read from the table
6TOTT = 14read from the table
8BETOB = 15read from the table
10ORBEO = 16read from the table
15TOBORT = 17read from the table
9EOTOBE = 18read from the table

The decoder was given 16 code(s) and the 6-character alphabet, and nothing else.

4 The one input where the decoder needs a code it has not built yet, and what it does instead

The round trip, and the one case where the decoder is asked for a code it has not built yet. Try AAAAAAAAAAAA or ABABABABABAB above to force it.

back out
TOBEORNOTTOBEORTOBEORNOT
identical to what went in
yes
symbols per code
1.50 (24 symbols, 16 codes)

On this input the decoder was never asked for a code it had not built. Try AAAAAAAAAAAA or ABABABABABAB to force the case.

These ran in this browser when the page loaded. Each claim, whether it held, and the number behind it.

Each claim, whether it held, and the values behind it
claimheldmeasured
every one of 6 inputs survives the round tripyestext in, same text out
and both ends hold the same dictionary, entry for entryyesidentical on every input
the decoder is asked for a code it has not built yet, on 3 of these inputsyesABABABABABAB, AAAAAAAAAAAA, aaabaaabaaab
and what it works out is what the encoder had, every timeyesforced, not guessed
twelve repeats pack to 2.40 symbols per code against 1.00 for twelve distinctyesrepetition is what it is paid for

What is real here, and what is not

Nothing here is packed into bits, so there is no compression ratio on this page

A real LZW encoder writes codes into a bit stream whose width grows as the table does — nine bits, then ten, then eleven — and the saving is measured in bits against the input’s bits. This page emits JavaScript numbers into an array. The only ratio it prints is symbols per code, which is a fact about the dictionary rather than about a file, and calling it compression would be a claim about a thing nobody ships.

The alphabet is derived from the input, not fixed at 256

A deployed encoder seeds the table from a fixed alphabet decided before anything is read, rather than from the input: TIFF from the 256 byte values, GIF from a code size the image header declares, which is why its first codes depend on the picture’s palette and not on this sentence. An earlier version of this entry said both formats seed with 256 byte values, which is not true of GIF and was corrected after an outside reader caught it. This page seeds the table with the distinct characters of whatever you typed, sorted, so the codes on screen are small enough to follow. That changes every code number from what a real encoder would emit and changes none of the mechanism.

The table never fills up here

Every deployed LZW has to decide what to do when the dictionary reaches its maximum code: GIF emits a clear code and starts again, and some encoders freeze the table instead. Neither is implemented. The strings this page accepts are far too short to reach any limit, so the case never arises and the page does not pretend to handle it.

The patent is over, and it is part of the story rather than a footnote

Unisys held US patent 4,558,302 on the algorithm and began enforcing it against GIF encoders in 1994, which is why PNG exists. The patent expired in 2003 and 2004 depending on jurisdiction. The page dates the machine 1984-1987 — Welch’s paper, then the patent grant and the compression formats that adopted it — and none of that is a claim about who invented what: LZW is Welch’s refinement of Lempel and Ziv’s 1978 algorithm and is named for all three.

Sources