Rumah > pembangunan bahagian belakang > Golang > Mengapa Python dan Go zlib menjana output termampat yang berbeza untuk input yang sama?

Mengapa Python dan Go zlib menjana output termampat yang berbeza untuk input yang sama?

DDD
Lepaskan: 2024-10-29 06:16:02
asal
716 orang telah melayarinya

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

Golang vs Python zlib: Membedah Perbezaan Output

Dalam coretan kod yang disediakan, anda cuba memampatkan rentetan menggunakan kedua-dua Python pakej flate zlib dan Go. Walau bagaimanapun, pelaksanaan Python anda menghasilkan output yang berbeza daripada rakan sejawat Go. Mengapakah ini berlaku?

Untuk membantu dalam penyahpepijatan, mari analisa serpihan kod yang berkaitan:

Pelaksanaan 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>
Salin selepas log masuk

Langkah utama dalam kod Go ialah menutup Writer, yang membuang data yang dimampatkan dan menulis jumlah semak hingga akhir.

Pelaksanaan 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>
Salin selepas log masuk

Di sini, anda telah memadamkan pemampat secara eksplisit dengan memanggil compressor.flush(zlib.Z_SYNC_FLUSH).

Membedah Output

Output Python mengandungi bait kelima daripada 0, manakala Go mempunyai 4. Yang pertama adalah hasil pengendalian Zlib pada akhir data. Yang terakhir adalah disebabkan oleh Flate menanggalkan pengepala dan checksum semasa menutup penulis.

Merapatkan Jurang Output

Untuk mendapatkan output yang setanding daripada kedua-dua pelaksanaan, anda boleh sama ada:

  1. Gunakan Flush() dalam Go: Gantikan w.Close() dengan w.Flush() dalam kod Go anda untuk mengeluarkan data termampat tanpa checksum.

    <code class="go">buf := new(bytes.Buffer)
     w, _ := flate.NewWriter(buf, 7)
     w.Write([]byte(source))
     w.Flush()
    
     return buf.Bytes()</code>
    Salin selepas log masuk
  2. Tweak Tetapan Zlib Python: Saya tidak meneroka secara peribadi jika anda boleh memaksa zlib Python untuk mengeluarkan strim DEFLATE lengkap tanpa pengepala atau checksum. Walau bagaimanapun, ini mungkin jalan yang bermanfaat untuk diteruskan.

Kesimpulan

Walaupun anda mungkin boleh mengubahsuai parameter untuk memaksa padanan bait demi bait antara kedua-dua pelaksanaan, ini tidak perlu atau diingini. Keserasian output antara perpustakaan mampatan berbeza dijamin tetapi tidak sama.

Atas ialah kandungan terperinci Mengapa Python dan Go zlib menjana output termampat yang berbeza untuk input yang sama?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan