Python: Implementierungen aufblasen und entleeren

Ich arbeite mit einem Server zusammen, für den die an ihn gesendeten Daten komprimiert werden müssenLuft ablassen Algorithmus (Huffman-Codierung + LZ77) und sendet auch Daten, die ich braucheAufblasen.

Ich weiß, dass Python Zlib enthält und dass die C-Bibliotheken in Zlib Aufrufe unterstützenAufblasen undLuft ablassen, aber diese werden anscheinend nicht vom Python Zlib-Modul bereitgestellt. Es bietetKomprimieren undDekomprimieren, aber wenn ich einen Anruf wie den folgenden tätige:

result_data = zlib.decompress( base64_decoded_compressed_string )

Ich erhalte folgende Fehlermeldung:

Error -3 while decompressing data: incorrect header check

Gzip macht es nicht besser; wenn Sie einen Anruf tätigen wie:

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

Ich erhalte den Fehler:

IOError: Not a gzipped file

Das macht Sinn, da die Daten aEntleert Datei nicht wahrGzipped Datei.

Jetzt weiß ich, dass es eine gibtLuft ablassen Implementierung vorhanden (Pyflate), aber ich kenne keineAufblasen Implementierung.

Es scheint, dass es einige Möglichkeiten gibt:

Finden Sie eine vorhandene Implementierung (ideal) vonAufblasen undLuft ablassen in PythonSchreiben Sie meine eigene Python-Erweiterung in die zlib c-Bibliothek, die Folgendes enthältAufblasen undLuft ablassenRufen Sie etwas anderes auf, das über die Befehlszeile ausgeführt werden kann (z. B. ein Ruby-Skript seitAufblasen/Luft ablassen Aufrufe in zlib sind vollständig in Ruby eingeschlossen.)?

Ich suche nach einer Lösung, aber da mir eine Lösung fehlt, bin ich dankbar für Einsichten, konstruktive Meinungen und Ideen.

Zusätzliche Information: Das Ergebnis der Deflationierung (und Codierung) eines Strings sollte für die von mir benötigten Zwecke dasselbe Ergebnis liefern wie das folgende C # -Code-Snippet, wobei der Eingabeparameter ein Array von UTF-Bytes ist, das den zu komprimierenden Daten entspricht:

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;
}

Wenn Sie diesen .NET-Code für die Zeichenfolge "deflate and encode me" ausführen, erhalten Sie das Ergebnis

7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8iZvl5mbV5mi1nab6cVrM8XeT/Dw==

Wenn "deflate and encode me" über Python Zlib.compress () ausgeführt und anschließend base64-codiert wird, lautet das Ergebnis "eJxLSU3LSSxJVUjMS1FIzUvOT0lVyE0FAFXHB6k =".

Es ist klar, dass zlib.compress () nicht die Implementierung des gleichen Algorithmus wie der Standard-Deflate-Algorithmus ist.

Mehr Informationen:

Die ersten 2 Bytes der .NET-Deflate-Daten ("7b0HY ...") nach der b64-Decodierung lauten 0xEDBD, was nicht den Gzip-Daten (0x1f8b), BZip2-Daten (0x425A) oder Zlib-Daten (0x789C) entspricht.

Die ersten 2 Bytes der Python-komprimierten Daten ("eJxLS ...") nach der b64-Dekodierung sind 0x789C. Dies ist ein Zlib-Header.

Gelöst

Um mit der Rohentleerung und dem Aufblasen ohne Header und Prüfsumme umzugehen, mussten die folgenden Dinge geschehen:

Beim Entleeren / Komprimieren: Entfernen Sie die ersten zwei Bytes (Header) und die letzten vier Bytes (Prüfsumme).

Beim Aufblasen / Dekomprimieren: Es gibt ein zweites Argument für die Fenstergröße. Wenn dieser Wert negativ ist, werden Header unterdrückt. Hier sind meine Methoden, einschließlich der Base64-Codierung / -Decodierung - und sie funktionieren ordnungsgemäß:

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 )

Antworten auf die Frage(2)

Ihre Antwort auf die Frage