Python: Infla y desinfla implementaciones

Estoy interactuando con un servidor que requiere que los datos que se le envíen estén comprimidos conDesinflar algoritmo (codificación Huffman + LZ77) y también envía los datos que necesitoInflar.

Sé que Python incluye Zlib y que las bibliotecas de C en Zlib admiten llamadas aInflar yDesinflar, pero aparentemente no son proporcionados por el módulo Zlib de Python. ProporcionaComprimir yDescomprimir, pero cuando hago una llamada como la siguiente:

result_data = zlib.decompress( base64_decoded_compressed_string )

Recibo el siguiente error:

Error -3 while decompressing data: incorrect header check

Gzip no lo hace mejor; al hacer una llamada como:

result_data = gzip.GzipFile( fileobj = StringIO.StringIO( base64_decoded_compressed_string ) ).read()

Recibo el error:

IOError: Not a gzipped file

lo que tiene sentido ya que los datos son unaDesinflado archivo no es un verdaderoComprimido expediente.

Ahora sé que hay unaDesinflar implementación disponible (Pyflate), pero no conozco unInflar implementación.

Parece que hay algunas opciones:

Encuentra una implementación existente (ideal) deInflar yDesinflar en PythonEscriba mi propia extensión de Python en la biblioteca zlib c que incluyeInflar yDesinflarLlame a otra cosa que pueda ejecutarse desde la línea de comandos (como un script Ruby, ya queInflar/Desinflar Las llamadas en zlib están completamente envueltas en Ruby.?

Estoy buscando una solución, pero si no tengo una solución, estaré agradecido por ideas, opiniones constructivas e ideas.

Información Adicional: El resultado de desinflar (y codificar) una cadena debe, para los fines que necesito, dar el mismo resultado que el siguiente fragmento de código C #, donde el parámetro de entrada es una matriz de bytes UTF que corresponde a los datos a comprimir:

public static string DeflateAndEncodeBase64(byte[] data)
{
    if (null == data || data.Length < 1) return null;
    string compressedBase64 = "";

    //write into a new memory stream wrapped by a deflate stream
    using (MemoryStream ms = new MemoryStream())
    {
        using (DeflateStream deflateStream = new DeflateStream(ms, CompressionMode.Compress, true))
        {
            //write byte buffer into memorystream
            deflateStream.Write(data, 0, data.Length);
            deflateStream.Close();

            //rewind memory stream and write to base 64 string
            byte[] compressedBytes = new byte[ms.Length];
            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(compressedBytes, 0, (int)ms.Length);
            compressedBase64 = Convert.ToBase64String(compressedBytes);
        }
    }
    return compressedBase64;
}

Ejecutar este código .NET para la cadena "desinflar y codificar" da el resultado

7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8iZvl5mbV5mi1nab6cVrM8XeT/Dw==

Cuando "deflate y codifíqueme" se ejecuta a través de Python Zlib.compress () y luego codificado en base64, el resultado es "eJxLSU3LSSxJVUjMS1FIzUvOT0lVyE0FAFXHB6k =".

Está claro que zlib.compress () no es una implementación del mismo algoritmo que el algoritmo de Desinflado estándar.

Más información:

Los primeros 2 bytes de los datos de desinflado .NET ("7b0HY ..."), después de la decodificación de b64 son 0xEDBD, que no corresponden a los datos Gzip (0x1f8b), BZip2 (0x425A) o Zlib (0x789C).

Los primeros 2 bytes de los datos comprimidos de Python ("eJxLS ..."), después de la decodificación de b64 son 0x789C. Este es un encabezado Zlib.

Resuelto

Para manejar el desinflado e inflado sin formato, sin encabezado ni suma de comprobación, deben suceder las siguientes cosas:

Al desinflar / comprimir: elimine los dos primeros bytes (encabezado) y los últimos cuatro bytes (suma de comprobación).

En inflar / descomprimir: hay un segundo argumento para el tamaño de la ventana. Si este valor es negativo, suprime los encabezados. Estos son mis métodos actualmente, incluida la codificación / decodificación de base64, y funcionan correctamente:

import zlib
import base64

def decode_base64_and_inflate( b64string ):
    decoded_data = base64.b64decode( b64string )
    return zlib.decompress( decoded_data , -15)

def deflate_and_base64_encode( string_val ):
    zlibbed_str = zlib.compress( string_val )
    compressed_string = zlibbed_str[2:-4]
    return base64.b64encode( compressed_string )

Respuestas a la pregunta(2)

Su respuesta a la pregunta