             switch code {
             case .byte(let byte):
                 try mainLiterals.code(symbol: byte.toInt(), &bitWriter, DeflateError.symbolNotFound)
-            case .lengthDistance(let ld):
-                try mainLiterals.code(symbol: ld.lengthSymbol, &bitWriter, DeflateError.symbolNotFound)
-                bitWriter.write(number: ld.lengthExtraBits, bitsCount: ld.lengthExtraBitsCount)
-
-                try mainDistances.code(symbol: ld.distanceSymbol, &bitWriter, DeflateError.symbolNotFound)
-                bitWriter.write(number: ld.distanceExtraBits, bitsCount: ld.distanceExtraBitsCount)
+            case .lengthDistance(let length, let distance):
+                let lengthSymbol = Constants.lengthCode[Int(length) - 3]
+                let lengthExtraBits = Int(length) - Constants.lengthBase[lengthSymbol - 257]
+                let lengthExtraBitsCount = (257 <= lengthSymbol && lengthSymbol <= 260) || lengthSymbol == 285 ?
+                    0 : (((lengthSymbol - 257) >> 2) - 1)
+                try mainLiterals.code(symbol: lengthSymbol, &bitWriter, DeflateError.symbolNotFound)
+                bitWriter.write(number: lengthExtraBits, bitsCount: lengthExtraBitsCount)
+
+                let distanceSymbol = ((Constants.distanceBase.index { $0 > Int(distance) }) ?? 30) - 1
+                let distanceExtraBits = Int(distance) - Constants.distanceBase[distanceSymbol]
+                let distanceExtraBitsCount = distanceSymbol == 0 || distanceSymbol == 1 ? 0 : ((distanceSymbol >> 1) - 1)
+                try mainDistances.code(symbol: distanceSymbol, &bitWriter, DeflateError.symbolNotFound)
+                bitWriter.write(number: distanceExtraBits, bitsCount: distanceExtraBitsCount)
             }
         }
 

                            repeatIndex = matchStartIndex + 1
                        }
                    }
                    let ld = LengthDistance(matchLength, distance)
                    buffer.append(BLDCode.lengthDistance(ld))
                    stats[ld.lengthSymbol] += 1
                    stats[286 + ld.distanceSymbol] += 1
                    inputIndex += matchLength
                } else {
                    buffer.append(BLDCode.byte(byte))

        return bitWriter.buffer
    }

    private enum BLDCode {
        case byte(UInt8)
        case lengthDistance(UInt16, UInt16)
    }

    private static func lengthEncode(_ rawBytes: [UInt8]) -> (codes: [BLDCode], stats: [Int]) {
