Heim > Backend-Entwicklung > Golang > Warum generieren Python und Go zlib unterschiedliche komprimierte Ausgaben für dieselbe Eingabe?

Warum generieren Python und Go zlib unterschiedliche komprimierte Ausgaben für dieselbe Eingabe?

DDD
Freigeben: 2024-10-29 06:16:02
Original
678 Leute haben es durchsucht

 Why do Python and Go zlib generate different compressed output for the same input?

Golang vs. Python zlib: Analyse der Ausgabeunterschiede

In den bereitgestellten Codefragmenten versuchen Sie, eine Zeichenfolge mit beiden Pythons zu komprimieren Das Flate-Paket von zlib und Go. Allerdings liefert Ihre Python-Implementierung eine andere Ausgabe als das Go-Gegenstück. Warum ist das so?

Um das Debuggen zu unterstützen, analysieren wir die relevanten Codefragmente:

Go-Implementierung (compress.go)

<code class="go">package main

import (
    "compress/flate"
    "bytes"
    "fmt"
)

func compress(source string) []byte {
    w, _ := flate.NewWriter(nil, 7)
    buf := new(bytes.Buffer)

    w.Reset(buf)
    w.Write([]byte(source))
    w.Close()

    return buf.Bytes()
}

func main() {
    example := "foo"
    compressed := compress(example)
    fmt.Println(compressed)
}</code>
Nach dem Login kopieren

Der wichtigste Schritt im Go-Code ist das Schließen des Writers, der die komprimierten Daten löscht und eine Prüfsumme ans Ende schreibt.

Python-Implementierung (compress.py)

<code class="python">from __future__ import print_function

import zlib


def compress(source):
    # golang zlib strips header + checksum
    compressor = zlib.compressobj(7, zlib.DEFLATED, -15)
    compressor.compress(source)
    # python zlib defaults to Z_FLUSH, but 
    # https://golang.org/pkg/compress/flate/#Writer.Flush
    # says "Flush is equivalent to Z_SYNC_FLUSH"
    return compressor.flush(zlib.Z_SYNC_FLUSH)


def main():
    example = u"foo"
    compressed = compress(example)
    print(list(bytearray(compressed)))


if __name__ == "__main__":
    main()</code>
Nach dem Login kopieren

Hier haben Sie den Kompressor explizit geleert, indem Sie compress.flush(zlib.Z_SYNC_FLUSH) aufgerufen haben.

Ausgabe zerlegen

Die Python-Ausgabe enthält ein fünftes Byte von 0, während Go 4 hat. Ersteres ist das Ergebnis der Behandlung des Datenendes durch Zlib. Letzteres ist darauf zurückzuführen, dass Flate beim Schließen des Writers den Header und die Prüfsumme entfernt.

Überbrückung der Ausgabelücke

Um eine vergleichbare Ausgabe beider Implementierungen zu erhalten, können Sie entweder:

  1. Verwenden Sie Flush() in Go: Ersetzen Sie w.Close() durch w.Flush() in Ihrem Go-Code, um die komprimierten Daten ohne Prüfsumme auszugeben.

    <code class="go">buf := new(bytes.Buffer)
     w, _ := flate.NewWriter(buf, 7)
     w.Write([]byte(source))
     w.Flush()
    
     return buf.Bytes()</code>
    Nach dem Login kopieren
  2. Python-Zlib-Einstellungen anpassen: Ich habe nicht persönlich untersucht, ob Sie Pythons Zlib zwingen können, den vollständigen DEFLATE-Stream ohne Header oder Prüfsummen auszugeben. Dies könnte jedoch ein fruchtbarer Weg sein.

Fazit

Während Sie möglicherweise Parameter anpassen können, um eine Byte-für-Byte-Übereinstimmung zu erzwingen zwischen den beiden Implementierungen ist dies weder notwendig noch wünschenswert. Die Ausgabekompatibilität zwischen verschiedenen Komprimierungsbibliotheken ist garantiert, aber nicht identisch.

Das obige ist der detaillierte Inhalt vonWarum generieren Python und Go zlib unterschiedliche komprimierte Ausgaben für dieselbe Eingabe?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage