Saltar al contenido
AZ Tools

Inspector de archivos gzip (.gz)

Un .gz no es un archivo comprimido al uso: es un flujo. Uno o más miembros concatenados, cada uno con su cabecera de 10 bytes, su propio flujo deflate y su tráiler de 8 bytes con un CRC32 y el ISIZE, la longitud sin comprimir módulo 2^32. Esta página los recorre todos y muestra lo que dice cada campo: la firma 1f 8b y el método de compresión, los cinco bits de FLG (FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT) y qué campos opcionales prometen, MTIME convertido a fecha —el 0 significa que nunca se puso, que es lo que escribe una compilación reproducible—, XFL (2 para compresión máxima, 4 para el algoritmo más rápido) y el byte de sistema operativo con su nombre, además de los subcampos FEXTRA separados en sus identificadores de dos bytes y sus contenidos, el nombre original, el comentario y el CRC16 de la cabecera. Después verifica. Cada miembro se descomprime en el propio navegador y se recalcula su CRC32 sobre el resultado, de modo que el tráiler se comprueba en lugar de repetirse: un archivo cuyo CRC32 no coincide está dañado de una forma que, si no, aparece a mitad de una restauración, cuando ya no queda el original. De ahí sale también el tamaño real sin comprimir, y por eso el total puede no cuadrar con gzip -l. gzip -l lee el ISIZE del último miembro y lo presenta como el tamaño de todo el archivo, así que en cualquier cosa construida con cat a.gz b.gz, o por un compresor paralelo como pigz en bloques independientes, se queda corto exactamente en lo que contienen los miembros anteriores. El ISIZE ocupa 32 bits, de modo que un miembro de más de 4 GB guarda su longitud módulo 2^32 y ningún lector puede recuperar el tamaño real solo con ese campo. La basura tras el último tráiler, un miembro que se corta a mitad del flujo y un archivo que no es gzip se identifican por su nombre en lugar de interpretarse a medias. El nombre guardado dentro del miembro —al que restaura gunzip -N, y que puede ser una ruta o algo muy distinto del archivo que tienes— se muestra tal cual: la norma dice ISO-8859-1, pero en la práctica lleva los bytes de la configuración regional, así que aparecen ambas lecturas cuando difieren.

Cómo usar

  1. Suelta un .gz, un .tgz o cualquier flujo gzip sobre el recuadro. Se analiza y se descomprime en la página; no se sube nada.
  2. Empieza por el resumen: cuántos miembros tiene el archivo de verdad, el total real sin comprimir y si todos los CRC32 coincidieron.
  3. Abre un miembro para ver su cabecera: los cinco bits de bandera, MTIME, XFL, el byte de sistema operativo, el nombre guardado, el comentario y los subcampos FEXTRA.
  4. Compara los dos pares del tráiler: el CRC32 guardado frente al CRC32 real de los datos, y el ISIZE frente al tamaño real. Que ambos coincidan es justo lo que comprueba gzip -t.
  5. En un archivo con varios miembros, fíjate en la diferencia entre la cifra de gzip -l y el total real antes de citar un tamaño sacado de gzip -l.

Preguntas frecuentes

¿Por qué gzip -l da un tamaño distinto al de esta página?
Porque gzip -l no descomprime nada. Salta a los últimos cuatro bytes del archivo, lee ese ISIZE y lo imprime como tamaño sin comprimir. En un archivo de un solo miembro es correcto. En uno hecho concatenando miembros —cat a.gz b.gz, un registro rotado añadido a un archivo, pigz o bgzip escribiendo bloques independientes— esos cuatro bytes describen únicamente al último miembro, así que gzip -l se deja fuera todo lo anterior. Esta página, en cambio, descomprime cada miembro y suma lo que realmente salió, y por eso puede mostrar un total mucho mayor. También implica que gzip -l es instantáneo y esta página no: el precio de la respuesta honesta es descomprimir el archivo.
¿Qué significa un MTIME de 0 y qué fecha guarda ese campo?
MTIME es la fecha de modificación del archivo original, en segundos desde la época Unix y en UTC; no es el momento en que se comprimió ni la fecha del .gz en disco. Un cero significa que no había fecha disponible o que se decidió no guardarla: gzip -n escribe 0 a propósito, y las compilaciones reproducibles hacen lo mismo, porque una marca de tiempo es la razón clásica de que dos compilaciones del mismo contenido den bytes distintos. Comprimir desde una tubería también da 0, ya que no hay archivo del que tomar la fecha. El campo son cuatro bytes, así que una fecha posterior a 2106 no se puede representar, y las implementaciones no se ponen de acuerdo sobre si un valor mayor que 2^31 es un futuro lejano o un número negativo.
El nombre original se ve como caracteres extraños. ¿Está dañado el archivo?
No: lo que falla es el formato. RFC 1952 dice que FNAME es una cadena ISO-8859-1 (Latin-1), pero gzip en Linux y macOS escribe directamente los bytes del nombre tal como los produjo la configuración regional, que hoy suele ser UTF-8. Por eso cualquier nombre fuera de ASCII solo viaja intacto entre sistemas con la misma codificación: un nombre escrito en UTF-8 y leído como Latin-1 devuelve los típicos acentos duplicados. Esta página muestra el campo decodificado como exige la norma y, cuando esos mismos bytes también son UTF-8 válido y dan otra lectura, la enseña al lado, para que veas los dos nombres candidatos y decidas cuál quiso escribir quien lo creó.
¿Qué demuestra exactamente un CRC32 que no coincide, y qué no demuestra uno que sí?
Que no coincida significa que los bytes que salen del flujo deflate no son los que entraron al escribirlo: un bit cambiado en el almacenamiento, una transferencia cortada y remendada, una edición sobre los datos comprimidos. Es el mismo fallo que gunzip informa como «invalid compressed data — crc error», salvo que aquí lo ves sin escribir la salida en ningún sitio. Que coincida solo demuestra que los datos son los que vio el compresor. El CRC32 es un código detector de errores de 32 bits, no una firma: detecta el daño accidental con probabilidad altísima, pero quien pueda cambiar los datos también puede recalcular el CRC. Para autenticidad hace falta un hash o una firma sobre el archivo, no su tráiler.
¿Puede mostrar los archivos que hay dentro de un .tar.gz?
No, y nada que lea solo gzip puede hacerlo. gzip comprime un único flujo de bytes y no sabe qué contiene: no hay índice, no hay entradas por archivo y no hay forma de extraer uno solo sin descomprimir todo lo anterior. Un .tar.gz es un archivo tar, que sí tiene esa estructura, pasado entero por gzip. Lo que esta página sí puede decirte es lo que registra la capa gzip: cuántos miembros hay, el nombre original de cada cabecera (a menudo archive.tar), la marca de tiempo y cuántos datos salen. Para listar las entradas necesitas un lector de tar trabajando sobre el flujo ya descomprimido.
¿Para qué sirven los subcampos FEXTRA?
FEXTRA es un punto de extensión: una serie de subcampos precedidos por su longitud, cada uno con un identificador de dos bytes, su propia longitud y su contenido, que un lector debe saltarse si no reconoce el identificador. Sus usos reales tienen que ver casi siempre con hacer que un flujo gzip se pueda recorrer por posiciones. BGZF, el formato tras bgzip y tras todos los BAM de genómica, escribe un subcampo «BC» con el tamaño de cada bloque para poder saltar directamente a un límite de bloque; dictzip guarda por el mismo motivo una tabla de longitudes bajo «RA». Ambos siguen siendo archivos gzip normales que gunzip lee sin enterarse, que es justo la gracia del mecanismo. Un subcampo poco común suele delatar que el archivo lo escribió una herramienta así.

Herramientas relacionadas