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.
| step | emits | for | adds |
|---|---|---|---|
| 1 | 5 | T | TO = 6 |
| 2 | 3 | O | OB = 7 |
| 3 | 0 | B | BE = 8 |
| 4 | 1 | E | EO = 9 |
| 5 | 3 | O | OR = 10 |
| 6 | 4 | R | RN = 11 |
| 7 | 2 | N | NO = 12 |
| 8 | 3 | O | OT = 13 |
| 9 | 5 | T | TT = 14 |
| 10 | 6 | TO | TOB = 15 |
| 11 | 8 | BE | BEO = 16 |
| 12 | 10 | OR | ORT = 17 |
| 13 | 15 | TOB | TOBE = 18 |
| 14 | 9 | EO | EOR = 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.
| code | means | adds | how |
|---|---|---|---|
| 5 | T | — (nothing yet) | read from the table |
| 3 | O | TO = 6 | read from the table |
| 0 | B | OB = 7 | read from the table |
| 1 | E | BE = 8 | read from the table |
| 3 | O | EO = 9 | read from the table |
| 4 | R | OR = 10 | read from the table |
| 2 | N | RN = 11 | read from the table |
| 3 | O | NO = 12 | read from the table |
| 5 | T | OT = 13 | read from the table |
| 6 | TO | TT = 14 | read from the table |
| 8 | BE | TOB = 15 | read from the table |
| 10 | OR | BEO = 16 | read from the table |
| 15 | TOB | ORT = 17 | read from the table |
| 9 | EO | TOBE = 18 | read 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.
| claim | held | measured |
|---|---|---|
| every one of 6 inputs survives the round trip | yes | text in, same text out |
| and both ends hold the same dictionary, entry for entry | yes | identical on every input |
| the decoder is asked for a code it has not built yet, on 3 of these inputs | yes | ABABABABABAB, AAAAAAAAAAAA, aaabaaabaaab |
| and what it works out is what the encoder had, every time | yes | forced, not guessed |
| twelve repeats pack to 2.40 symbols per code against 1.00 for twelve distinct | yes | repetition 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
- T. A. Welch, A Technique for High-Performance Data Compression, IEEE Computer 17(6), June 1984, pages 8-19. The publisher’s page is the canonical identifier and extracts as nothing, so the archived copy of this citation is empty; it is here as a reference rather than as a witness.
- J. Ziv and A. Lempel, Compression of Individual Sequences via Variable-Rate Coding, IEEE Transactions on Information Theory 24(5), 1978. The LZ78 algorithm Welch's is a refinement of. The publisher’s page is the canonical identifier and extracts as nothing, so the archived copy of this citation is empty; it is here as a reference rather than as a witness.
- Logical Art, the studio this belongs to.