2009-09-03 12 views
10

Estoy escribiendo una aplicación que necesita descomprimir datos comprimidos por otra aplicación (que está fuera de mi control, no puedo hacer cambios en su código fuente). La aplicación de productor utiliza zlib para comprimir datos utilizando el mecanismo z_stream. Utiliza Z_FULL_FLUSH con frecuencia (probablemente con demasiada frecuencia, en mi opinión, pero eso es otro asunto). Esta aplicación de terceros también puede descomprimir sus propios datos, por lo que estoy bastante seguro de que los datos son correctos.zlib decompression failure

En mi prueba, estoy usando esta tercera parte aplicación para comprimir el siguiente archivo de texto simple (en hexadecimal):

48 65 6c 6c 6f 20 57 6f 72 6c 64 21 0d 0a

Los bytes comprimidos que recibo de la aplicación de este aspecto (de nuevo , en hexadecimal):

78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

Si trato y comprimir los mismos datos, consigo resultados muy similares:

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

Hay dos diferencias que puedo ver:

En primer lugar, el cuarto byte es F2, en lugar de F3, por lo poco no se ha establecido "bloque final" del desinflado. Supongo que esto se debe a que la interfaz de transmisión nunca sabe cuándo llegará el final de los datos entrantes, por lo que nunca establece ese bit. Por último, los últimos cuatro bytes en los datos externos son 00 00 FF FF, mientras que en mis datos de prueba es 24 E9 04 55. Buscando en que encontré en esta página

http://www.bolet.org/~pornin/deflate-flush.html

... que esta es una firma de una sincronización o descarga completa.

Cuando intento y descomprimo mis propios datos usando la función decompress(), todo funciona perfectamente. Sin embargo, cuando intento y descomprimo los datos externos, la llamada a la función decompress() falla con un código de retorno de Z_DATA_ERROR, que indica datos corruptos.

Tengo algunas preguntas:

  1. ¿Debo ser capaz de utilizar el "descomprimir" zlib función para descomprimir los datos que han sido comprimidos con el método z_stream?

  2. En el ejemplo anterior, ¿cuál es el significado de los últimos cuatro bytes? Dado que tanto el flujo de datos comprimido externamente como mi propia corriente de datos de prueba tienen la misma longitud, ¿qué representan los últimos cuatro bytes?

Saludos

+0

No tengo ni idea de esto, pero una información potencialmente relevante que se olvidó de agregar a su pregunta es cómo falla la descompresión de zlib. –

+0

Gracias, eso también. – Thomi

Respuesta

7

, gracias a los autores de zlib, he encontrado la respuesta.La aplicación de terceros está generando corrientes zlib que no están terminados correctamente:

78 9c f2 48 cd C9 C9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

Es una secuencia zlib parcial, que consta de un encabezado zlib y una secuencia de deflación parcial . Hay dos bloques , ninguno de los cuales es un último bloque . El segundo bloque es un bloque almacenado vacío , utilizado como un marcador cuando descarga. Un decodificador zlib sería decodificar correctamente lo que hay allí, y luego continúe buscando datos después de esos bytes.

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

Eso es una corriente zlib completa, que consiste en una cabecera zlib, una sola bloque marcado como el último bloque y zlib trailer. El trailer es la suma de comprobación Adler-32 de los datos sin comprimir .

Mi descompresión está fallando, probablemente porque falta el CRC o el código de descompresión sigue buscando más datos que no existen.