Algoritmo LZ77 explicado: ¿cómo funciona la compresión de diccionario?

Conclusión primero: LZ77 es un algoritmo de compresión de diccionario basado en ventana deslizante, cuya idea central es "usar los datos históricos como diccionario y referenciar hacia atrás cuando se encuentra contenido repetido". Al codificar, se emite un triplete (distance, length, next_char): se retrocede distance caracteres para encontrar una coincidencia, la longitud de coincidencia es length, seguida de un carácter no coincidente next_char. Tomando como ejemplo los 11 caracteres de "abracadabra", la codificación LZ77 solo necesita 5 tripletes para representarlos, con un efecto de compresión significativo. LZ77 es un componente central de DEFLATE (ZIP/GZIP/PNG) y el ancestro común de algoritmos de compresión modernos como LZSS/LZMA/LZ4. A continuación se explica el principio de la ventana deslizante y se demuestra paso a paso el proceso de codificación.

Si aún no está familiarizado con los principios de la codificación Huffman, le recomendamos leer primero Principios de la codificación Huffman: la base de los algoritmos de compresión.

1. ¿Qué es la compresión de diccionario?

Los algoritmos de compresión se dividen en dos grandes corrientes: la codificación estadística (como la codificación Huffman) asigna códigos de longitud variable según la frecuencia de caracteres; la compresión de diccionario sustituye el contenido repetido por "referencias de puntero". LZ77 pertenece a la corriente de compresión de diccionario: no construye una tabla de diccionario previamente, sino que usa los datos históricos ya procesados como diccionario implícito — cuando encuentra contenido repetido, usa un "puntero de retroceso" para señalar una posición donde apareció anteriormente.

Corriente de compresiónPrincipio centralAlgoritmos representativosVentajaDesventaja
Codificación estadísticaAsigna códigos de longitud variable por frecuenciaHuffman, codificación aritméticaAproxima el límite entrópicoNo maneja bien repetición de largo alcance
Compresión de diccionarioSustituye contenido repetido por referenciasLZ77, LZW, LZMAManeja bien patrones repetidosIneficaz con datos aleatorios
Codificación híbridaDiccionario + estadística en dos fasesDEFLATE, ZSTDÓptimo globalImplementación más compleja
Codificación por transformadaTransforma al dominio frecuencial y cuantizaDCT(JPEG), DWTAlta eficiencia en compresión con pérdidaPérdida de información

En la práctica, los algoritmos de compresión más populares son casi todos "codificación híbrida" — primero usan LZ77 para eliminar patrones repetidos, luego Huffman para comprimir los residuos por frecuencia. DEFLATE es la combinación clásica de LZ77 + Huffman, ampliamente utilizada por ZIP, GZIP y PNG.

2. Principios del algoritmo LZ77 en detalle

El núcleo de LZ77 es el mecanismo de ventana deslizante. La ventana se divide en dos partes: el buffer de búsqueda (datos históricos ya procesados) y el buffer de previsualización (datos futuros por procesar). Al codificar, se toma un segmento del buffer de previsualización y se busca la coincidencia más larga en el buffer de búsqueda; si se encuentra, se emite un triplete; si no, se emite el carácter original.

1. Estructura de la ventana deslizante

El tamaño de la ventana deslizante determina directamente el efecto de compresión — cuanto mayor sea la ventana, más datos históricos se pueden buscar en retroceso y mayor será la probabilidad de coincidencia. Los tamaños de ventana varían mucho entre diferentes algoritmos.

AlgoritmoBuffer de búsquedaBuffer de previsualizaciónLongitud máxima de coincidenciaEscenario típico
LZ77 originalAlgunos KBDecenas de bytes16 bytesEjemplo didáctico
DEFLATE32KB258 bytes258 bytesZIP/GZIP/PNG
LZMA8MB (configurable)273 bytes273 bytesArchivado 7z/xz
LZ464KBSin límiteSin límiteCompresión en tiempo real
ZSTD8MB (máx. 1GB)Sin límiteSin límiteUso general moderno

2. Formato de codificación de triplete

La unidad de salida de LZ77 es el triplete (distance, length, next_char), cuyos tres campos se explican en la siguiente tabla.

CampoSignificadoRango de valores (DEFLATE)Bits de codificaciónEjemplo
distanceDistancia de retroceso (cuántos caracteres hacia atrás buscar)1–3276815 bitdistance=10 → 10 caracteres hacia atrás
lengthLongitud de coincidencia (cuántos caracteres coinciden consecutivamente)3–2588 bitlength=5 → 5 caracteres coincidentes
next_charEl siguiente carácter tras la coincidencia0–2558 bitnext_char='d' → ASCII 100

La genialidad del triplete radica en que, tras la coincidencia, se emite un next_char adicional, garantizando que el codificador siempre avance al menos 1 carácter y no se bloquee. Si no se encuentra ninguna coincidencia (length=0), tanto distance como length son 0 y solo se emite next_char — equivalente a degenerar en almacenamiento de carácter original.

3. Estrategia de búsqueda de coincidencias

La búsqueda de coincidencias es el cuello de botella de rendimiento de LZ77 — se toma un segmento del buffer de previsualización y se busca la coincidencia más larga en el buffer de búsqueda. La búsqueda por fuerza bruta tiene complejidad O(n×m); las implementaciones reales usan tablas hash o árboles de sufijos para acelerar.

Estrategia de búsquedaEstructura de datosComplejidad de búsquedaCoste espacialAplicación típica
Búsqueda por fuerza brutaNingunaO(n×m)NingunoEjemplo didáctico
Cadena hashTabla hash + lista enlazadaO(n) promedioBajozlib (DEFLATE)
Cubeta hashTabla hash + arrayO(1) promedioMedioLZ4
Árbol de sufijosÁrbol de sufijos / array de sufijosO(n) peor casoAltoLZMA

3. Caso práctico: demostración de codificación de "abracadabra"

Se realiza una codificación completa de "abracadabra" (11 caracteres) con LZ77. El estado inicial tiene el buffer de búsqueda vacío y el buffer de previsualización contiene toda la cadena. Se escanea posición por posición, buscando la coincidencia más larga en los datos históricos.

Texto original: a b r a c a d a b r a

Proceso de codificación:

PasoPosición actualContenido de previsualizaciónBúsqueda en bufferTriplete de salidaDescripción
1Posición 1abracadabraVacío, sin coincidencia(0, 0, 'a')Primer carácter, salida directa
2Posición 2bracadabra"a", sin coincidencia "b"(0, 0, 'b')Primera aparición, salida directa
3Posición 3racadabra"ab", sin coincidencia "r"(0, 0, 'r')Primera aparición, salida directa
4Posición 4acadabraEncontrado "a" en "abr"(0, 0, 'a')"a" aparece pero no coincide después
5Posición 5cadabraSin "c" en "abra"(0, 0, 'c')Primera aparición, salida directa
6Posición 6adabraEncontrado "a" en "abrac"(0, 0, 'a')"a" coincide pero no después
7Posición 7dabraSin "d" en "abraca"(0, 0, 'd')Primera aparición, salida directa
8Posición 8abraRetroceso 7, coincide "abra"(7, 4, end)Coinciden 4 caracteres "abra"

Comparación de eficiencia de codificación:

Método de codificaciónNº de unidades de salidaBits por unidadBits totalesAhorro vs original
ASCII original11 caracteres888— (base)
LZ77 (sin optimización de coincidencia)8 tripletes31 (promedio)248-182% (expansión)
LZ77 (optimización de bits de marca)8 unidades12 (promedio)96-9% (ligera expansión)
LZ77+Huffman8 unidades4.5 (promedio)3659%

Análisis de resultados: El LZ77 puro puede expandir cadenas cortas (el triplete ocupa más espacio que el carácter original), por eso LZ77 se suele combinar con codificación Huffman — DEFLATE es LZ77 + Huffman. En el caso de "abracadabra", la coincidencia en la posición 8 "abra" (distance=7, length=4) es el punto de compresión clave: 4 caracteres representados por un solo triplete. Para textos más largos con más patrones repetidos (como archivos de código, logs), el efecto de compresión de LZ77 mejora significativamente.

4. Variantes de LZ77 y evolución moderna

Desde su propuesta en 1977, LZ77 ha dado lugar a numerosas variantes, cada una optimizando una dimensión para un escenario específico. La siguiente tabla compara los miembros principales de la familia LZ77.

AlgoritmoMejora claveTasa de compresiónVelocidad de compresiónVelocidad de descompresiónAplicación típica
LZ77 (original)Codificación de tripleteBajaLentaMediaDocencia
LZSSUsa bits de marca para distinguir coincidencia/literalMediaMediaRápidaSistemas antiguos
DEFLATELZSS + Huffman en dos fasesMedia-altaMediaRápidaZIP/GZIP/PNG
LZMAVentana grande + codificación de intervalos + análisis óptimoAltaLentaMediaArchivado 7z/xz
LZ4Sacrifica tasa de compresión por velocidad extremaBajaMuy rápidaMuy rápida (4GB/s)Tiempo real / kernel
LZWTabla de diccionario explícita (no ventana deslizante)MediaRápidaRápidaGIF/TIFF
ZSTDVariante LZ77 + FSE + diccionario preestablecidoAltaRápidaMuy rápidaUso general moderno

Desde la perspectiva de la evolución, los algoritmos modernos (ZSTD, brotli) han mejorado drásticamente la velocidad manteniendo una alta tasa de compresión, reemplazando gradualmente a DEFLATE como nuevo estándar. Pero la idea central de LZ77 — la referencia de diccionario por ventana deslizante — permanece inalterada, y todas las variantes se construyen sobre esta base.

EscenarioAlgoritmo recomendadoMotivoReferencia de tasa de compresión
Archivado de archivosLZMA (xz)Tasa de compresión más alta, sin priorizar velocidad70%–85%
Compresión generalZSTDEquilibra tasa de compresión y velocidad60%–80%
Transmisión en tiempo realLZ4Descompresión a 4GB/s, latencia muy baja50%–65%
Transmisión WebDEFLATE/GZIPMejor compatibilidad, todos los navegadores50%–70%
Formato de imagenDEFLATE (PNG)Compresión sin pérdida, ideal para gráficos50%–75%
Datos en memoriaLZ4Bajo uso de CPU, ideal para compresión frecuente50%–65%

Para más detalles sobre la aplicación específica de DEFLATE en el formato PNG, consulte Principios de compresión PNG explicados. Para la diferencia entre compresión sin pérdida y con pérdida, consulte Compresión sin pérdida vs con pérdida: diferencias clave.

5. Preguntas frecuentes (FAQ)

P1: ¿Qué es el algoritmo LZ77?

LZ77 es un algoritmo de compresión de diccionario basado en ventana deslizante, propuesto por Lempel y Ziv en 1977. La idea central es: usar los datos ya procesados como diccionario; cuando se encuentra contenido repetido, se sustituyen los datos originales por un triplete (distance, length, next_char), donde distance indica la distancia de retroceso, length indica la longitud de coincidencia, y next_char indica el siguiente carácter tras la coincidencia. LZ77 es un componente central de DEFLATE (ZIP/GZIP/PNG) y el ancestro de algoritmos modernos como LZSS/LZMA/LZ4.

P2: ¿Qué significa la ventana deslizante de LZ77?

La ventana deslizante es la estructura de datos central de LZ77, dividida en buffer de búsqueda (datos históricos ya procesados) y buffer de previsualización (datos futuros por procesar). Al codificar, se toma un segmento del buffer de previsualización y se busca la coincidencia más larga en el buffer de búsqueda. El tamaño típico de ventana es 32KB (estándar DEFLATE); cuanto mayor sea la ventana, mayor será la probabilidad de coincidencia, pero también el consumo de memoria. El tamaño de ventana determina el límite superior de la distancia máxima de retroceso (distance).

P3: ¿Cuál es la diferencia entre LZ77 y LZ78?

LZ77 usa una ventana deslizante como diccionario implícito: el contenido coincidente referencia directamente los datos históricos sin almacenar un diccionario separado; LZ78 usa una tabla de diccionario explícita, numerando las cadenas ya vistas y almacenándolas como entradas de diccionario, emitiendo índices de diccionario al codificar. LZ77 es más adecuado para datos con repetición local (como texto), mientras que LZ78 es más adecuado para datos con repetición global. En la práctica, los descendientes de LZ77 (DEFLATE/LZMA/LZ4) son mucho más populares que los de LZ78 (LZW).

P4: ¿Cuál tiene mayor tasa de compresión: LZ77, LZMA o LZ4?

Orden de tasa de compresión: LZMA > LZ77 (DEFLATE) > LZ4. LZMA usa una ventana más grande (8MB por defecto), algoritmos de coincidencia más avanzados y codificación de intervalos, logrando la mayor tasa de compresión pero la velocidad más lenta; DEFLATE usa ventana de 32KB + Huffman, con tasa de compresión y velocidad medias; LZ4 sacrifica la tasa de compresión por velocidad extrema, con la tasa de compresión más baja pero una velocidad de descompresión de hasta 4GB/s. La elección depende del escenario: archivado → LZMA, uso general → DEFLATE/ZSTD, tiempo real → LZ4.

Resumen

LZ77 es el progenitor de los algoritmos de compresión de diccionario, cuyo principio central es "ventana deslizante + referencia de triplete": usa los datos históricos como diccionario implícito y, al encontrar contenido repetido, emite un triplete (distance, length, next_char). El LZ77 puro puede expandir textos cortos, pero combinado con codificación Huffman (DEFLATE) se convierte en el esquema de compresión estándar de ZIP/GZIP/PNG. La variante moderna LZMA persigue la máxima tasa de compresión, LZ4 persigue la máxima velocidad, y ZSTD equilibra ambas.

Tres puntos clave para entender LZ77: primero, la ventana deslizante determina el rango de coincidencia (DEFLATE 32KB, LZMA 8MB); segundo, el triquete es la unidad básica de codificación (retroceso + longitud + siguiente carácter); tercero, la estrategia de búsqueda de coincidencias determina el rendimiento (cadena hash es la más rápida, árbol de sufijos es la más óptima). La codificación híbrida LZ77 + Huffman es el estándar de oro de la compresión sin pérdida moderna.

¿Necesita comprimir archivos? Pruebe SmartSlim

Construido sobre un motor de compresión Rust propio, compatible con 10 categorías y más de 40 formatos, incluyendo PDF, imágenes, vídeo, Office y OFD, con compresión local que mantiene sus datos en sus instalaciones.