调试Python的zlib和golang的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)
}
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
结果
$ 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]
Run Code Online (Sandbox Code Playgroud)
Python版本有0
第五个字节,但golang版本有4
- 导致不同输出的原因是什么?
python 示例的输出不是“完整”流,它只是在压缩第一个字符串后刷新缓冲区。Close()
您可以通过替换为从 Go 代码中获得相同的输出Flush()
:
https://play.golang.org/p/BMcjTln-ej
func compress(source string) []byte {
buf := new(bytes.Buffer)
w, _ := flate.NewWriter(buf, 7)
w.Write([]byte(source))
w.Flush()
return buf.Bytes()
}
Run Code Online (Sandbox Code Playgroud)
但是,您正在比较 python 中 zlib 的输出(它在内部使用 DEFLATE 来生成 zlib 格式输出)和flate
Go 中的 zlib 输出(这是一个 DEFLATE 实现)。我不知道是否可以让 python zlib 库输出原始的、完整的 DEFLATE 流,但尝试让不同的库输出压缩数据的逐字节匹配似乎没有用或可维护。压缩库的输出仅保证兼容,而不保证相同。