Python 2.7: Compresión de datos con el formato XZ usando el módulo “lzma”

Estoy experimentando con el módulo lzma en Python 2.7.6 para ver si puedo crear archivos comprimidos usando el formato XZ para un proyecto futuro que lo usará. Mi código utilizado durante el experimento fue:

import lzma as xz in_file = open('/home/ki2ne/Desktop/song.wav', 'rb') input_data = in_file.read() compressed_data = xz.compress(input_data) out_file = open('/home/ki2ne/Desktop/song.wav.xz', 'wb') in_file.close() out_file.close() 

y noté que había dos sums de comprobación diferentes (MD5 y SHA256) del archivo resultante en comparación con cuando usé el xz simple (aunque podía descomprimir bien con cualquiera de los métodos, las sums de comprobación de las versiones descomprimidas de ambos archivos eran iguales). ¿Sería esto un problema?

ACTUALIZACIÓN: Encontré una solución al instalar el backport (de Python 3.3) a través del repository Git de peterjc ( enlace aquí ), y ahora muestra sums de comprobación idénticas. No estoy seguro de si ayuda, pero me aseguré de que el módulo LZMA Python en mi repository no estuviera instalado para evitar posibles conflictos de nombres.

Aquí está mi código de prueba para confirmar esto:

 # I have created two identical text files with some random phrases from subprocess import call from hashlib import sha256 from backports import lzma as xz f2 = open("test2.txt" , 'rb') f2_buf = buffer(f2.read()) call(["xz", "test1.txt"]) f2_xzbuf = buffer(xz.compress(f2_buf)) f1 = open("test1.txt.xz", 'rb') f1_xzbuf = buffer(f1.read()) f1.close(); f2.close() f1sum = sha256(); f2sum = sha256() f1sum.update(f1_xzbuf); f2sum.update(f2_xzbuf) if f1sum.hexdigest() == f2sum.hexdigest(): print "Checksums OK" else: print "Checksum Error" 

También lo verifiqué utilizando la sha256sum regular (cuando escribí los datos en el archivo).

    No me preocuparían las diferencias en los archivos comprimidos: según el formato del contenedor y el tipo de sum de comprobación utilizado en el archivo .xz , los datos comprimidos pueden variar sin afectar el contenido.

    EDITAR He estado investigando esto y escribí este script para probar el módulo PyLZMA Python2.x y el módulo lzma Python3.x incorporado

     from __future__ import print_function try: import lzma as xz except ImportError: import pylzma as xz import os # compress with xz command line util os.system('xz -zkf test.txt') # now compress with lib with open('test.txt', 'rb') as f, open('test.txt.xzpy', 'wb') as out: out.write(xz.compress(bytes(f.read()))) # compare the two files from hashlib import md5 with open('test.txt.xz', 'rb') as f1, open('test.txt.xzpy', 'rb') as f2: hash1 = md5(f1.read()).hexdigest() hash2 = md5(f2.read()).hexdigest() print(hash1, hash2) assert hash1 == hash2 

    Esto comprime un archivo test.txt con la utilidad de línea de comandos xz y con el módulo Python y compara los resultados. Bajo Python3, lzma produce el mismo resultado que xz , sin embargo, bajo Python2, PyLZMA produce un resultado diferente que no se puede extraer con la utilidad de línea de comandos xz.

    ¿Qué módulo está utilizando que se llama “lzma” en Python2 y qué comando usó para comprimir los datos?

    EDIT 2 Bien, encontré el módulo pyliblzma para Python2. Sin embargo, parece que utiliza CRC32 como el algoritmo de sum de comprobación predeterminado (otros usan CRC64) y hay un error que evita cambiar el algoritmo de sum de comprobación https://bugs.launchpad.net/pyliblzma/+bug/1243344

    Posiblemente podría intentar comprimir usando xz -C crc32 para comparar los resultados, pero todavía no estoy teniendo éxito al hacer un archivo comprimido válido usando las bibliotecas de Python2.

    En mi caso (Ubuntu / Mint), para usar el módulo lzma con Pyhton 2.7, instalé backports.lzma directamente con pip (no he usado github), con sudo o usuario root :

     pip2 install backports.lzma 

    FYI pip2 tiene la opción --user que no requiere permisos de superusuario e instala el módulo solo para el usuario local, pero no lo he probado.

    Primero que realizar la instalación pip , también debe instalar, con su administrador de paquetes, una dependencia obligatoria : la biblioteca liblzma .

    En mi caso, los nombres de los paquetes fueron liblzma5 y liblzma-dev pero los nombres de los paquetes pueden diferir entre las distribuciones / versiones de Linux.

    Ps: También repetí la misma operación con éxito con conda en un entorno Linux diferente (distro de clúster desconocido):

     conda install backports conda install backports.lzma --name pyEnvName 

    Esperanza útil