1
votes

I am trying to compress a string in my Android app (Java) and then decompress it on the server with Python. I tried using the Inflater class, but then I get an "error: Error -3 while decompressing data: incorrect header check" on the python side. On the python side, I'm using zlib to decompress:

data_string = zlib.decompress(compressed_string)

On the Android side, we are using Deflater to compress:

String stringData = commentData == null ? sleepData.toString() : sleepData.toString() + commentData.toString();

byte[] bytes = stringData.getBytes("UTF-8");
int length = bytes.length;
Deflater deflater = new Deflater();
deflater.setInput(bytes);
deflater.finish();
byte[] compressedBytes = new byte[length];
deflater.deflate(compressedBytes);
deflater.end();

How can I decompress in python the string that the app is sending?

Thanks!

EDITS: This is what we are sending from Android and are feeding into the decompress command: (the dots represent just more of the same - there are a lot of zeros and then some "0b's" in the end: "78efbfbdefbfbdefbfbdefbfbd6e1b2....efbfbd190000000.....0000‌​000000000b0b0b0b0b0b‌​0b0b0b0b0b

Things we have tried:

-- data_string = zlib.decompress(decrypted,-zlib.MAX_WBITS), which gives a new error: "Error -3 while decompressing data: invalid stored block lengths"

-- data_string = zlib.decompressobj(decrypted,15+32) and data_string = zlib.decompress(compressed_string, 16+zlib.MAX_WBITS) which both give the initial error "invalid header check".

1
How are you sending the data from the Android/Java side to the Server/Python side? - Robᵩ
That should work, since Deflater by default produces the zlib format, and zlib.decompress() by default is expecting the zlib format. Can you provide the first several bytes of what you are feeding to zlib.decompress(), in hex? - Mark Adler
This is what the string looks like: (the dots represent just more of the same - there are a lot of zeros and then some "0b's" in the end: "78efbfbdefbfbdefbfbdefbfbd6e1b2....efbfbd190000000.....0000000000000b0b0b0b0b0b0b0b0b0b0b" - Maria
as for the sending of the data - we first compress, then encrypt with AES256 on the Android side, and then send it to the server, where we decrypt, then try to decompress. Before we added the compression, the encrypt/decrypt part was working fine. - Maria

1 Answers

1
votes

Add 16+zlib.MAX_WBITS or 15 + 32 as the second [optional] wbits arg in decompress: https://docs.python.org/2/library/zlib.html#zlib.decompress

data_string = zlib.decompress(compressed_string, 16+zlib.MAX_WBITS)

EDIT: Depending on how you're passing the compressed bytes to Python, it's likely your issue is with how Python is reading your compressed bytes.

I recommend using Base64 encoding on the compressed bytes in Java, then decoding the base64 in Python then decompressing those bytes in this vein...

Java:

String inputString = "blahblahblah";
byte[] input = inputString.getBytes("UTF-8");

// Compress the bytes
byte[] output = new byte[100];
Deflater compresser = new Deflater();
compresser.setInput(input);
compresser.finish();
int compressedDataLength = compresser.deflate(output);
compresser.end();
System.out.println(Base64.getEncoder().encodeToString(output)); 

Python:

import base64
import zlib
base64_binary = b"eJxLyknMSIJiAB8CBMYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
deflate_bytes=base64.decodebytes(base64_binary)
zlib.decompress(deflate_bytes)
# b'blahblahblah'

Related:

How can I decompress a gzip stream with zlib?

Python decompressing gzip chunk-by-chunk

Byte Array in Python