¿Son compatibles zlib.compress en Python y Deflater.deflate en Java (Android)?

Estoy portando una aplicación de Python a Android y, en algún momento, esta aplicación tiene que comunicarse con un Servicio Web, enviándolo datos comprimidos.

Para ello se utiliza el siguiente método:

def stuff(self, data): "Convert into UTF-8 and compress." return zlib.compress(simplejson.dumps(data)) 

Estoy usando el siguiente método para intentar emular este comportamiento en Android:

 private String compressString(String stringToCompress) { Log.i(TAG, "Compressing String " + stringToCompress); byte[] input = stringToCompress.getBytes(); // Create the compressor with highest level of compression Deflater compressor = new Deflater(); //compressor.setLevel(Deflater.BEST_COMPRESSION); // Give the compressor the data to compress compressor.setInput(input); compressor.finish(); // Create an expandable byte array to hold the compressed data. // You cannot use an array that's the same size as the orginal because // there is no guarantee that the compressed data will be smaller than // the uncompressed data. ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length); // Compress the data byte[] buf = new byte[1024]; while (!compressor.finished()) { int count = compressor.deflate(buf); bos.write(buf, 0, count); } try { bos.close(); } catch (IOException e) { } // Get the compressed data byte[] compressedData = bos.toByteArray(); Log.i(TAG, "Finished to compress string " + stringToCompress); return new String(compressedData); } 

Pero la respuesta HTTP del servidor no es correcta y supongo que es porque el resultado de la compresión en Java no es el mismo que el de Python.

Corrí una pequeña prueba de compresión "a" con zlib.compress y desinflar.

Python, zlib.compress () -> x% 9CSJT% 02% 00% 01M% 00% A6

Android, Deflater.deflate -> H% EF% BF% BDK% 04% 00% 00b% 00b

¿Cómo debo comprimir los datos en Android para obtener el mismo valor de zlib.compress () en Python?

Cualquier ayuda, orientación o puntero es muy apreciado!

    Comprimir y desinflar son diferentes algoritmos de compresión por lo que la respuesta es que no será compatible. Como un ejemplo de la diferencia aquí es 'a' comprimido usando los dos algoritmos vía Tcl:

     % binary encode hex [zlib compress a] 789c4b040000620062 % binary encode hex [zlib deflate a] 4b0400 

    Su código de python es realmente hacer compresión. Y el código de Android está haciendo deflate, sin embargo, también está recibiendo la marca de orden de bytes UTF-8 antes de la versión android (\ xef \ xbf \ xbf)

    Puede emitir datos de desinflado utilizando python:

     def deflate(data): zobj = zlib.compressobj(6,zlib.DEFLATED,-zlib.MAX_WBITS,zlib.DEF_MEM_LEVEL,0) zdata = zobj.compress(data) zdata += zobj.flush() return zdata 
     >>> deflate("a") 'K\x04\x00' 

    Aunque no son exactamente los mismos algoritmos, parece que son totalmente compatibles (lo que significa que si se comprime, por ejemplo, una cadena utilizando Deflater.deflate puede descomprimirlo mediante zlib).

    Lo que causó mi problema fue que todas las variables de formulario en un POST necesitan ser por ciento de escape, y la aplicación de Android no lo estaba haciendo. Codificar los datos a Base64 antes de enviarlo, y modificar el servidor para decodificarlo usando Base64 antes de descomprimirlo utilizando zlib resolvió el problema.

    ¿El byte[] input = stringToCompress.getBytes("utf-8"); ¿ayuda? En caso de que su plataforma de codificación por defecto no es UTF-8, esto obligará a la cadena de codificación -> bytes para utilizar UTF-8. Igualmente, lo mismo ocurre con la última línea del código en la que se crea una new String – es posible que desee especificar explícitamente UTF-8 como Charset de descodificación.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.