LZMA is LZ77 (literals and copies from a sliding window) whose decisions and values
are all coded one bit at a time by an adaptive binary range coder. This page
summarises the decoder in
lzma-specification.txt
from the LZMA SDK, read 2026-11-12; the
same coding is inside LZMA2,
7z and lzip.
Range decoder
- Start:
Range = FFFFFFFF; read 5 bytes intoCode. The first byte must be 0, andCodeequal toRangemarks the stream as corrupted; in an undamaged streamCodeis always less thanRange. - Normalise: whenever
Rangefalls below 224, shiftRangeandCodeleft 8 bits and read the next byte intoCode. - Probability bits: each probability is an 11-bit number (out of 2,048) that the
next bit is 0, starting at 1,024.
bound = (Range >> 11) × prob. IfCode < boundthe bit is 0:Range = bound,prob += (2048 − prob) >> 5. Otherwise it is 1:Range −= bound,Code −= bound,prob −= prob >> 5. - Direct bits, with probability one half:
Range >>= 1; the bit is 1 ifCode ≥ Range, which is then subtracted. - A bit tree of n bits decodes a number from the top bit down, using 2n probabilities indexed by the bits read so far; a reverse bit tree reads the low bit first.
Packets
The decoder keeps the position pos, the state (0 to 11), the previous byte
and four repeat distances rep0 to rep3.
posState = pos & ((1 << pb) − 1). Each packet starts with
decision bits:
| Bits | Packet | Meaning |
|---|---|---|
0 | LIT | A literal byte. |
1 0 | MATCH | A length and a new distance. |
1 1 0 0 | SHORTREP | One byte from distance rep0. |
1 1 0 1 | LONGREP[0] | A length, distance rep0. |
1 1 1 0 | LONGREP[1] | A length, distance rep1. |
1 1 1 1 0 | LONGREP[2] | A length, distance rep2. |
1 1 1 1 1 | LONGREP[3] | A length, distance rep3. |
The bits come from these probability arrays: IsMatch[state][posState],
IsRep[state], IsRepG0[state],
IsRep0Long[state][posState], IsRepG1[state] and
IsRepG2[state]. A repeat moves the distance it used to rep0
and shifts the others down; a MATCH pushes its new distance in as rep0
and drops rep3.
States
The state remembers the kinds of the last few packets. States 0 to 6 follow a literal; 7 to 11 follow a match or repeat.
| After | New state |
|---|---|
| LIT | 0 if state < 4; state − 3 if state < 10; else state − 6 |
| MATCH | 7 if state < 7, else 10 |
| LONGREP | 8 if state < 7, else 11 |
| SHORTREP | 9 if state < 7, else 11 |
Literals
There are 0x300 << (lc + lp) literal probabilities, 0x300 for each
context. The context is
((pos & ((1 << lp) − 1)) << lc) + (prevByte >> (8 − lc)).
In states below 7 the byte is an 8-bit tree. From state 7 up (just after a match) it
is a “matched literal”: the byte at distance rep0 is used as a guide, and
while its bits agree with the bits decoded, a separate set of probabilities chosen by
the guide bit is used. (The specification’s prose says “state > 7”, but its
decoder code tests state >= 7.)
Lengths
MATCH and LONGREP use two length decoders of the same shape, one each. Lengths run from 2 to 273:
| Bits | Length | Coded as |
|---|---|---|
0 | 2 to 9 | 3-bit tree, one per posState (low) |
1 0 | 10 to 17 | 3-bit tree, one per posState (mid) |
1 1 | 18 to 273 | 8-bit tree, shared (high) |
Distances
lenState = min(len − 2, 3). Decode a 6-bit tree fromPosSlot[lenState]: the distance slot, 0 to 63.- Slots 0 to 3 are the distance itself.
- Otherwise
numDirectBits = (slot >> 1) − 1and the distance starts as(2 | (slot & 1)) << numDirectBits. - Slots 4 to 13: the low
numDirectBitsbits are a reverse bit tree in theSpecPosprobabilities. - Slots 14 to 63:
numDirectBits − 4direct bits, then the low 4 bits as a reverse 4-bit tree in theAlignprobabilities.
The decoded value is the distance minus 1. A value of FFFFFFFF is the
end marker. Otherwise it must be smaller than the data decoded so far and the
dictionary size.
Constants
| Name | Value |
|---|---|
kNumBitModelTotalBits | 11 (probabilities out of 2,048) |
kNumMoveBits | 5 |
kNumStates | 12 |
kMatchMinLen | 2 |
kEndPosModelIndex | 14 |
kNumFullDistances | 128 |
kNumAlignBits | 4 |
kNumLenToPosStates | 4 |