調試Python的zlib和golang的zlib之間的區別。以下爲什麼不具有相同的結果?golang/python zlib區別
compress.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)
}
compress.py
:
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()
結果
$ go version
go version go1.7.3 darwin/amd64
$ go build compress.go
$ ./compress
[74 203 207 7 4 0 0 255 255]
$ python --version
$ python 2.7.12
$ python compress.py
[74, 203, 207, 7, 0, 0, 0, 255, 255]
Python的版本有0
第五個字節,但golang版本有4
- 是什麼導致不同的輸出?
zlib使用DEFLATE實現,但flate和zlib不一樣。在這裏,你正在關閉flate流,而在python中,你只是在沖洗。如果將Go代碼更改爲'Flush()',則輸出將相同。還要注意不同的實現不能保證產生相同的二進制輸出,它們只能保證產生兼容的輸出。 – JimB
@ jimb:https://golang.org/pkg/compress/flate/說:「Package flate實現了RFC 1951中描述的DEFLATE壓縮數據格式...」,這似乎與第一句相矛盾,或者我誤解了你(或docs =))。同樣,https://golang.org/pkg/compress/flate/#Writer.Close聲明刷新作者並在'w.Write(...)'行添加一個明確的'w.Flush()'後添加更多的填充/校驗和字節。你介意提供一些更詳細的信息,因爲我明顯沒有遵循這些內容。 – everial
該輸出與python輸出相匹配:https://play.golang.org/p/_SCAspI3Mq。我不明白你發現什麼矛盾;你在python中使用zlib,它在內部使用DEFLATE來產生一個zlib格式的輸出,而你的Go例子直接使用DEFLATE實現。我不知道是否可以讓python zlib庫輸出原始完整的DEFLATE流,但是試圖讓不同的庫輸出壓縮數據的逐字節匹配似乎不是有用或可維護的。 – JimB