Golang と Python zlib: 出力の違いを分析する
提供されたコード スニペットでは、両方の Python の zlib を使用して文字列を圧縮しようとしています。 zlib と Go の flate パッケージ。ただし、Python 実装では Go 実装とは異なる出力が生成されます。なぜそうなるのでしょうか?
デバッグを支援するために、関連するコードの断片を分析してみましょう:
Go 実装 (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>
Go コードの重要なステップは、ライターを閉じることです。これにより、圧縮データがフラッシュされ、チェックサムが最後まで書き込まれます。
Python 実装 (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>
ここでは、compressor.flush(zlib.Z_SYNC_FLUSH) を呼び出してコンプレッサーを明示的にフラッシュしました。
出力の分析
Python の出力には以下が含まれます5 番目のバイトは 0 ですが、Go では 4 になります。前者は、Zlib によるデータの終わりの処理の結果です。後者は、ライターを閉じるときに Flate がヘッダーとチェックサムを削除するためです。
出力ギャップのブリッジング
両方の実装から同等の出力を取得するには、次のいずれかを実行できます。
Go で Flush() を使用する: Go コードで w.Close() を w.Flush() に置き換えて、チェックサムなしの圧縮データを出力します。
<code class="go">buf := new(bytes.Buffer) w, _ := flate.NewWriter(buf, 7) w.Write([]byte(source)) w.Flush() return buf.Bytes()</code>
結論
パラメータを微調整してバイトごとの一致を強制することもできるかもしれません。 2 つの実装の間では、これは必要ではなく、望ましくさえありません。異なる圧縮ライブラリ間の出力互換性は保証されていますが、同一ではありません。
以上がPython と Go zlib が同じ入力に対して異なる圧縮出力を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。