zlib.error: Error -3 durante la descompresión: verificación de encabezado incorrecta
⏰ 7 minutos de lectura
Varun Vyas
Tengo un archivo gzip y estoy tratando de leerlo a través de Python como se muestra a continuación:
import zlib
do = zlib.decompressobj(16+zlib.MAX_WBITS)
fh = open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
data = do.decompress(cdata)
arroja este error:
zlib.error: Error -3 while decompressing: incorrect header check
¿Cómo puedo superarlo?
dnozay
Tienes este error:
zlib.error: Error -3 while decompressing: incorrect header check
Lo cual es más probable porque está tratando de verificar encabezados que no están allí, por ejemplo, sus datos siguen RFC 1951 (deflate formato comprimido) en lugar de RFC 1950 (zlib formato comprimido) o RFC 1952 (gzip formato comprimido).
elegir ventanaBits
Pero zlib puede descomprimir todos esos formatos:
(des)comprimir deflate formato, uso wbits = -zlib.MAX_WBITS
(des)comprimir zlib formato, uso wbits = zlib.MAX_WBITS
(des)comprimir gzip formato, uso wbits = zlib.MAX_WBITS | 16
@dnozay, he intentado usar lo anterior zlib.decompress(zlib_data, zlib.MAX_WBITS|32) ajuste que mencionaste, pero no ha funcionado. todavía tengo el incorrect header check error. Si trato de usar las otras opciones mencionadas anteriormente, sigo recibiendo varios errores. ¿Hay algo más que pueda desencadenar este error?
– Minuto
24 mar. 17 a las 21:00
@Minu, seguro: cualquier tipo de datos que no sea un contenido válido desinflado, zlib o gzip fallaría en la verificación del encabezado.
– Charles Duffy
25 ago. 17 en 16:46
zlib.MAX_WBITS | 16 funcionó para mí, gracias. Es sorprendentemente no trivial deducir esto de la documentación. Además, es molesto que aiohttp no decodifica Content-Encoding: gzip transparentemente.
– usuario4815162342
10 dic. 17 en 19:03
Dave Bacher
Actualizar: la respuesta de dnozay explica el problema y debería ser la respuesta aceptada.
Prueba el gzip módulo, el código a continuación es directamente del documentos de Python.
import gzip
f = gzip.open('/home/joe/file.txt.gz', 'rb')
file_content = f.read()
f.close()
Se presentó el mismo error: Rastreo (última llamada más reciente): Archivo ““, línea 1, en Archivo “/usr/lib/python2.6/gzip.py”, línea 212, en read self._read (readsize) Archivo “/usr/lib/python2.6/gzip.py”, línea 271, en _read uncompress = self.decompress.decompress(buf) zlib.error: Error -3 al descomprimir: conjunto de longitudes de código no válidas
– Varun Vyas
26 jun.
@VarunVyas, lo siento, no puedo reproducir tu error. Debe tener algo que ver con los datos de entrada. ¿Se generó su archivo de entrada con gzip? ¿Gunzip desde la línea de comandos lo descomprime correctamente?
– Dave Bacher
26 jun.
Acabo de resolver el problema de “comprobación de encabezado incorrecto” al descomprimir datos comprimidos con gzip.
Debe configurar -WindowBits => WANT_GZIP en su llamada a inflateInit2 (use la versión 2)
Sí, esto puede ser muy frustrante. Una lectura típicamente superficial de la documentación presenta a Zlib como una API para la compresión Gzip, pero por defecto (sin usar los métodos gz*) no crea ni descomprime el formato Gzip. Tienes que enviar esta bandera documentada no muy prominente.
Asclepio
Para descomprimir bytes comprimidos con gzip incompletos que están en la memoria, la respuesta de dnozay es útil pero pierde el zlib.decompressobj llamada que considero necesaria:
Tenga en cuenta que zlib.MAX_WBITS | 16 es 15 | 16 que es 31. Para algunos antecedentes sobre wbits, ver zlib.decompress.
Crédito: respuesta de Yann Vernier que señala el zlib.decompressobj llamar.
djvg
Esto no responde a la pregunta original, pero puede ayudar a alguien más que termine aquí.
El zlib.error: Error -3 while decompressing: incorrect header check también ocurre en el siguiente ejemplo:
b64_encoded_bytes = base64.b64encode(zlib.compress(b'abcde'))
encoded_bytes_representation = str(b64_encoded_bytes) # this the cause
zlib.decompress(base64.b64decode(encoded_bytes_representation))
El ejemplo es una reproducción mínima de algo que encontré en algún código Django heredado, donde Base64 los bytes codificados (de un HTTP POST) se almacenaban en un Django CharField (en vez de una BinaryField).
Al leer un CharField valor de la base de datos, str() se llama sobre el valor, sin que un explícito encoding, como puede verse en la Fuente Django.
Si no se proporciona codificación ni errores, str(objeto) devuelve objeto.calle(), que es la representación de cadena “informal” o bien imprimible del objeto. Para objetos de cadena, esta es la propia cadena. Si el objeto no tiene un calle(), entonces str() recurre a devolver repr(objeto).
Entonces, en el ejemplo, sin darnos cuenta estamos decodificando en base64
"b'eJxLTEpOSQUABcgB8A=='"
en vez de
b'eJxLTEpOSQUABcgB8A=='.
El zlib descompresión en el ejemplo tendría éxito si un explícito encoding se usaron, por ejemplo str(b64_encoded_bytes, 'utf-8').
NOTA específica para Django:
Lo que es especialmente complicado: este problema solo surge cuando recuperando un valor de la base de datos. Véase, por ejemplo, la siguiente prueba, que pasa (en Django 3.0.3):
class MyModelTests(TestCase):
def test_bytes(self):
my_model = MyModel.objects.create(data=b'abcde')
self.assertIsInstance(my_model.data, bytes) # issue does not arise
my_model.refresh_from_db()
self.assertIsInstance(my_model.data, str) # issue does arise
donde MyModel es
class MyModel(models.Model):
data = models.CharField(max_length=100)
Pablo D. Waite
Curiosamente, tuve ese error al intentar trabajar con la API de desbordamiento de pila usando Python.
Me las arreglé para hacerlo funcionar con el GzipFile objeto del directorio gzip, más o menos así:
Mi caso fue descomprimir mensajes de correo electrónico que están almacenados en la base de datos Bullhorn. El fragmento es el siguiente:
import pyodbc
import zlib
cn = pyodbc.connect('connection string')
cursor = cn.cursor()
cursor.execute('SELECT TOP(1) userMessageID, commentsCompressed FROM BULLHORN1.BH_UserMessage WHERE DATALENGTH(commentsCompressed) > 0 ')
for msg in cursor.fetchall():
#magic in the second parameter, use negative value for deflate format
decompressedMessageBody = zlib.decompress(bytes(msg.commentsCompressed), -zlib.MAX_WBITS)
.
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información