0

Im trying to decompress a string in java, the string is compress in python with base64 encoding.

I tried a day to resolve the issue, The file can decode easily online and also in python. Find similar post that people have trouble compressing and decompressing in java and python.

zip.txt

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class CompressionUtils {
private static final int BUFFER_SIZE = 1024;

public static byte[] decompress(final byte[] data) {
    final Inflater inflater = new Inflater();
    inflater.setInput(data);
    ByteArrayOutputStream outputStream =
            new ByteArrayOutputStream(data.length);
    byte[] buffer = new byte[data.length];
    try {
        while (!inflater.finished()) {
            final int count = inflater.inflate(buffer);
            outputStream.write(buffer, 0, count);
        }
        outputStream.close();
    } catch (DataFormatException | IOException e) {
        e.printStackTrace();
        log.error("ZlibCompression decompress exception: {}", e.getMessage());
    }
    inflater.end();
    return outputStream.toByteArray();
}

public static void main(String[] args) throws IOException {
    decompress(Base64.getDecoder().decode(Files.readAllBytes(Path.of("zip.txt"))));
}
}

Error:

 java.util.zip.DataFormatException: incorrect header check
    at java.base/java.util.zip.Inflater.inflateBytesBytes(Native Method)
    at java.base/java.util.zip.Inflater.inflate(Inflater.java:378)
    at java.base/java.util.zip.Inflater.inflate(Inflater.java:464) 

Tried also this after @Mark Adler suggestion.

public static void main(String[] args) throws IOException {
    
    byte[] decoded = Base64.getDecoder().decode(Files.readAllBytes(Path.of("zip.txt")));
    ByteArrayInputStream in = new ByteArrayInputStream(decoded);
    GZIPInputStream gzStream = new GZIPInputStream(in);
    decompress(gzStream.readAllBytes());
    gzStream.close();
}

java.util.zip.DataFormatException: incorrect header check
at java.base/java.util.zip.Inflater.inflateBytesBytes(Native Method)
at java.base/java.util.zip.Inflater.inflate(Inflater.java:378)
at java.base/java.util.zip.Inflater.inflate(Inflater.java:464)
at efrisapi/com.efrisapi.util.CompressionUtils.decompress(CompressionUtils.java:51)
at efrisapi/com.efrisapi.util.CompressionUtils.main(CompressionUtils.java:67)
Aqeel Haider
  • 603
  • 7
  • 24
  • The `zip.txt` file seems to contain base64 data as you mention. If you decode it and save it as a ZIP file, can you open it with your operating system ZIP file manager? – Hernán Alarcón Jul 17 '22 at 23:38
  • The txt in the file is string. you can see the string when upload to link https://codebeautify.org/zlib-decompress-online – Aqeel Haider Jul 17 '22 at 23:41

2 Answers2

2

That is a gzip stream, not a zlib stream. Use GZIPInputStream.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • How do you know it’s a Gzip? – Aqeel Haider Jul 17 '22 at 23:44
  • I looked at it. – Mark Adler Jul 18 '22 at 00:26
  • I will try to check the header also to see if its Gzip, also kindly if you can explain how you manage to identify its a Gzip, it will help me also. also please check i have tried with GZIPInputStream but getting same error, i also tried with wrapon, but no avail. Thank you – Aqeel Haider Jul 18 '22 at 09:08
  • 1
    I just wrote a code that I tried to read this file as a gzip stream and got this message "java.util.zip.ZipException: Not in GZIP format". So, I don't think this a gzip format – Michael Gantman Jul 18 '22 at 09:37
  • @MichaelGantman Yes, it is. Did you decode the Base64 encoding first? – Mark Adler Jul 18 '22 at 14:21
  • @AqeelHaider I decoded the Base64 and ungzipped the result. The 18633 byte gzip stream decompresses to 114814 bytes of json data, which starts with _{"countryCode":[{"description":"SJ-Svalbard and Jan Mayen Islands","name":"SJ-Svalbard and Jan Mayen Islands","value":"SJ"}_... – Mark Adler Jul 18 '22 at 14:23
  • @MarkAdler No, I didn't decode Base64 first. So, I guess you are right – Michael Gantman Jul 18 '22 at 14:38
  • No one just _looks_ at the data anymore. It's obvious it's Base64 if you just look at it. – Mark Adler Jul 18 '22 at 16:06
  • Thank you i was looking in wrong direction, trying to decompress it using zlib. – Aqeel Haider Jul 18 '22 at 20:48
0

I was looking in to wrong direction, the string was gzipped, below is the code to resolve it. Thank you @Mark Adler for identifying the issue.

public static void deCompressGZipFile(String gZippedFile, String newFile) throws IOException {
    byte[] decoded = Base64.getDecoder().decode(Files.readAllBytes(Path.of(gZippedFile)));
    ByteArrayInputStream in = new ByteArrayInputStream(decoded);
    GZIPInputStream gZIPInputStream = new GZIPInputStream(in);
    FileOutputStream fos = new FileOutputStream(newFile);
    byte[] buffer = new byte[1024];
    int len;
    while ((len = gZIPInputStream.read(buffer)) > 0) {
        fos.write(buffer, 0, len);
    }
    // Keep it in finally
    fos.close();
    gZIPInputStream.close();
}
Aqeel Haider
  • 603
  • 7
  • 24