1

In my android app, it downloads a huge huge string from php. I want to compress it to save bandwidth. I found this page http://php.net/manual/en/function.gzcompress.php which allows me to compress it in php. But once I have it in android, how can I get back the original string?

Thanks

omega
  • 40,311
  • 81
  • 251
  • 474
  • see http://stackoverflow.com/questions/11402813/how-to-compress-a-jsonobject-send-it-over-http-in-android and http://stackoverflow.com/questions/7153484/gzip-post-request-with-httpclient-in-java – Shayan Pourvatan Nov 09 '14 at 06:36

2 Answers2

2

In my case I needed to decompress a string in PHP which was compressed in Android and visa versa and these strings were transported by RabbitMQ.

Here is how I solved it: In Android:

public static byte[] compress(String string) throws IOException {
    // string = "Lorem ipsum shizzle ma nizle";
    byte[] data = string.getBytes("UTF-8");
    ByteArrayOutputStream os = new ByteArrayOutputStream( data.length );
    GZIPOutputStream gos = new GZIPOutputStream(os);
    gos.write( data );
    gos.close();
    os.close();
    return os.toByteArray();
}

public static String decompress(byte[] compressed) throws IOException {
    final int BUFFER_SIZE = compressed.length;
    ByteArrayInputStream is = new ByteArrayInputStream(compressed);
    GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);
    StringBuilder string = new StringBuilder();
    byte[] data = new byte[BUFFER_SIZE];
    int bytesRead;
    while ((bytesRead = gis.read(data)) != -1) {
        string.append(new String(data, 0, bytesRead));
    }
    gis.close();
    is.close();
    return string.toString();
}

RabbitMQ Calls from Android:

.
.
// Publish
chan.basicPublish(EXCHANGE, routing_key, MessageProperties.PERSISTENT_BASIC, compress(message.payload));
.
.
// Subscribe
String message = decompress(body);
.
.
.

From the RabbitMQ management plugin I retrieved the Base64 encoded version of the string in Latin, and ran it against this test app in PHP to see which decompression methodology works.

<?php

$data = "Lorem ipsum shizzle ma nizle";
// try all the compression algorithms and out the results in Hex format
echo "\n\n\n";
for($i=-1;$i<=9;$i++)
    echo chunk_split(strtoupper(bin2hex(gzcompress($data,$i))),2," ") . PHP_EOL  ;
echo "\n\n";
for($i=-1;$i<=9;$i++)
    echo chunk_split(strtoupper(bin2hex(gzdeflate($data,$i))),2," ") . PHP_EOL  ;
echo "\n\n";
for($i=-1;$i<=9;$i++)
    echo chunk_split(strtoupper(bin2hex(gzencode($data,$i,FORCE_GZIP))),2," ")  . PHP_EOL;
echo "\n\n";
for($i=-1;$i<=9;$i++)
    echo chunk_split(strtoupper(bin2hex(gzencode($data,$i,FORCE_DEFLATE))),2," ") . PHP_EOL;
echo "\n\n";


// add the Base64 encoded text from the RabbitMQ plugin
$data = "H4sIAAAAAAAAAPPJL0rNVcgsKC7NVSjOyKyqyklVyE1UyMsEMgCX3v4lHAAAAA==";
$data = base64_decode($data);
// output the binary version of the compressed string in Hex format
echo chunk_split(strtoupper(bin2hex($data)),2," ") . PHP_EOL  ;
// match the HEX string to the samples from above as there may be an offset that you need to deal with

// finally see which of the decompression methods work
echo gzuncompress($data)."\n";
echo gzinflate($data)."\n";
echo gzdecode($data)."\n";

// Double check that you have the correct one
$data = "Lorem ipsum shizzle ma nizle";
echo chunk_split(strtoupper(bin2hex(gzencode($data,9,FORCE_GZIP))),2," ")  . PHP_EOL;
$data = gzencode($data,9,FORCE_GZIP);
echo gzdecode($data)."\n";

Thanks

0

Looks like it is just using gzip compression. If that's the case, take a look at:

http://developer.android.com/reference/java/util/zip/GZIPInputStream.html

If that isn't exactly the compression algorithm being used, there are a few more built in algorithms you can use as needed:

http://developer.android.com/reference/java/util/zip/package-summary.html

Joey
  • 464
  • 2
  • 9