ホームページ > バックエンド開発 > Golang > Python と Go zlib が同じ入力に対して異なる圧縮出力を生成するのはなぜですか?

Python と Go zlib が同じ入力に対して異なる圧縮出力を生成するのはなぜですか?

DDD
リリース: 2024-10-29 06:16:02
オリジナル
709 人が閲覧しました

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

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 がヘッダーとチェックサムを削除するためです。

出力ギャップのブリッジング

両方の実装から同等の出力を取得するには、次のいずれかを実行できます。

  1. 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 の Zlib 設定を調整する: ヘッダーやチェックサムのない完全な DEFLATE ストリームを Python の zlib に出力させることができるかどうか、私は個人的に調べていません。ただし、これは追求するのに有益な手段である可能性があります。

結論

パラメータを微調整してバイトごとの一致を強制することもできるかもしれません。 2 つの実装の間では、これは必要ではなく、望ましくさえありません。異なる圧縮ライブラリ間の出力互換性は保証されていますが、同一ではありません。

以上がPython と Go zlib が同じ入力に対して異なる圧縮出力を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート