Search code examples
javascriptjavanode.jsdeflateinflate

Deflate in Java, Inflate in Javascript, Z_DATA_ERROR


I need to deflate some text in java, send it to NodeJS with WebSockets and inflate it in NodeJS.

I use this code in Java to make compressed UTF-8 string in Java

public static String compress(String s) throws UnsupportedEncodingException 
{
    Deflater def = new Deflater(9);
    byte[] sbytes = s.getBytes(StandardCharsets.UTF_8);
    def.setInput(sbytes);
    def.finish();
    byte[] buffer = new byte[sbytes.length];
    int n = def.deflate(buffer);
    return new String(buffer, StandardCharsets.UTF_8);
            //+ "*" + sbytes.length;
    //return Base64.encode(buffer);
}

And this code to decompress in Javascript

zlib.inflate(new Buffer(message, "utf8"), function(err, data){
    if(!err){
        console.log(data.toString('utf8'));
    }else{
        console.log(err);
    }
});

message is a string from websocket

In NodeJS I get this error

{ Error: invalid code lengths set
    at Inflate.zlibOnError (zlib.js:152:15) errno: -3, code: 'Z_DATA_ERROR' }

To find an issue, I tried to use base64 and it works fine.

zlib.inflate(new Buffer(message, "base64"), function(err, data){
    if(!err){
        console.log(data.toString('utf8'));
    }else{
        console.log(err);
    }
});

Also i tried to inflate\deflate strings in Java and Javascript. Something strange happens while trying to make buffer in javascript from utf-8 string from Java. UTF-8 strings are same but buffers a bit different. Beggings of the buffers are the same by the way.

Update: Answer: Use Base64 instead of UTF-8


Solution

  • It isn't a good idea to represent binary data using a UTF-8 string encoding, see Encoding to use to convert Bytes array to String and vice-versa for a similar problem. Just base64 encode the data instead (see https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html).