首页 >后端开发 >Golang >为什么 Python 和 Go zlib 对于相同的输入生成不同的压缩输出?

为什么 Python 和 Go zlib 对于相同的输入生成不同的压缩输出?

DDD
DDD原创
2024-10-29 06:16:02681浏览

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

Golang 与 Python zlib:剖析输出差异

在提供的代码片段中,您尝试使用 Python 和 Python 来压缩字符串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 代码中的关键步骤是关闭 Writer,它会刷新压缩数据并将校验和写入末尾。

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 输出包含第五个字节为 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 设置: 我个人还没有探索过是否可以强制 Python 的 zlib 输出没有标头或校验和的完整 DEFLATE 流。然而,这可能是一个富有成效的追求途径。

结论

虽然您可以调整参数以强制逐字节匹配在两种实现之间,这是没有必要的,甚至是不需要的。不同压缩库之间的输出兼容性有保证,但不完全相同。

以上是为什么 Python 和 Go zlib 对于相同的输入生成不同的压缩输出?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn