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>
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>
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:
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>
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!