>백엔드 개발 >Golang >Python과 Go zlib가 동일한 입력에 대해 서로 다른 압축 출력을 생성하는 이유는 무엇입니까?

Python과 Go zlib가 동일한 입력에 대해 서로 다른 압축 출력을 생성하는 이유는 무엇입니까?

DDD
DDD원래의
2024-10-29 06:16:02682검색

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

Golang 대 Python zlib: 출력 차이 분석

제공된 코드 조각에서 두 Python의 zlib을 모두 사용하여 문자열을 압축하려고 합니다. 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>

여기에서는 압축기.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으로 문의하세요.