Heim >Backend-Entwicklung >Golang >Warum generieren Python und Go zlib unterschiedliche komprimierte Ausgaben für dieselbe Eingabe?
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>
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>
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:
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>
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!