Golang vs Python zlib : disséquer les différences de sortie
Dans les extraits de code fournis, vous essayez de compresser une chaîne en utilisant les deux langages de Python Le package flate de zlib et Go. Cependant, votre implémentation Python produit un résultat différent de celui de son homologue Go. Pourquoi est-ce le cas ?
Pour faciliter le débogage, analysons les fragments de code pertinents :
Implémentation 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>
L'étape clé du code Go consiste à fermer le Writer, qui vide les données compressées et écrit une somme de contrôle à la fin.
Implémentation 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>
Ici, vous avez explicitement vidé le compresseur en appelant compresseur.flush(zlib.Z_SYNC_FLUSH).
Disséquer la sortie
La sortie Python contient un cinquième octet de 0, alors que Go en a 4. Le premier est le résultat de la gestion par Zlib de la fin des données. Ce dernier est dû au fait que Flate a supprimé l'en-tête et la somme de contrôle lors de la fermeture du rédacteur.
Combler l'écart de sortie
Pour obtenir un résultat comparable des deux implémentations, vous pouvez soit :
Utilisez Flush() dans Go : Remplacez w.Close() par w.Flush() dans votre code Go pour émettre les données compressées sans la somme de contrôle.
<code class="go">buf := new(bytes.Buffer) w, _ := flate.NewWriter(buf, 7) w.Write([]byte(source)) w.Flush() return buf.Bytes()</code>
Conclusion
Bien que vous puissiez peut-être modifier les paramètres pour forcer une correspondance octet par octet entre les deux implémentations, cela n’est ni nécessaire ni même souhaitable. La compatibilité de sortie entre les différentes bibliothèques de compression est garantie mais pas identique.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!