java.util.zip.DataFormatException: неправильная проверка заголовка при выкачивании в JavaScript, а затем в Java

У меня есть большие данные на странице, и мне нужно опубликовать их на сервере.

поэтому я использую https://github.com/dankogai/js-deflate, чтобы сдуть большой данные.

Вроде работает нормально.

привет мир -> w4tIw43DicOJL8OPL8OKSQEA

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<h1>Demo</h1>
<p>$Id: demo.html,v 0.4 2013/04/09 14:25:38 dankogai Exp dankogai $</p>
<dl>
<dt>Inflated + Base64-Decoded (Original):</dt>
<dd><textarea id="inflated" cols="64" rows="16" onkeyup="(function(that, dst){
  setTimeout(function(){
    dst.value = Base64.toBase64(RawDeflate.deflate(Base64.utob(that.value)));
  },0)
})(this,$('deflated'))"></textarea></dd>
<dt>Deflated + Base64-Encoded (Compressed):</dt>
<dd><textarea id="deflated" cols="64" rows="16" onkeyup="(function(that, dst){
  setTimeout(function(){
    dst.value = Base64.btou(RawDeflate.inflate(Base64.fromBase64(that.value)));
  },0);
})(this, $('inflated'))"></textarea></dd>
</dl>
<script src="./base64.js"></script>
<script src="../rawinflate.js"></script>
<script src="../rawdeflate.js"></script>
<script>
$ = function(id){ return document.getElementById(id) };
</script>
</body>
</html>

введите здесь описание изображения

поэтому я хочу получить hellowold, поместив результат deflate в код Java. Я получил ошибку:

java.util.zip.DataFormatException: incorrect header check

введите здесь описание изображения

следующий мой код:

public static void main(String[] args) throws IOException {

        try {
            // Encode a String into bytes
            String output1 = "w4tIw43DicOJL8OPL8OKSQEA";

            byte[] output2 = Base64Util.decode(output1);

            // Decompress the bytes
            Inflater decompresser = new Inflater();
            decompresser.setInput(output2);

            System.out.println("a:" + new String(output2));

            byte[] result = new byte[100];
            int resultLength = decompresser.inflate(result);
            decompresser.end();

            // Decode the bytes into a String
            String outputString = new String(result, 0, resultLength, "UTF-8");
            System.out.println("b:" + outputString);

        } catch (java.io.UnsupportedEncodingException ex) {
            ex.printStackTrace();
            // handle
        } catch (java.util.zip.DataFormatException ex) {
            ex.printStackTrace();
            // handle
        }

    }

так в чем проблема?

И это мой класс Base64Util, который я тестировал. Ничего страшного:

public class Base64Util {

    private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();

    private static int[]  toInt   = new int[128];

    static {
        for(int i=0; i< ALPHABET.length; i++){
            toInt[ALPHABET[i]]= i;
        }
    }

    /**
     * Translates the specified byte array into Base64 string.
     *
     * @param buf the byte array (not null)
     * @return the translated Base64 string (not null)
     */
    public static String encode(byte[] buf){
        int size = buf.length;
        char[] ar = new char[((size + 2) / 3) * 4];
        int a = 0;
        int i=0;
        while(i < size){
            byte b0 = buf[i++];
            byte b1 = (i < size) ? buf[i++] : 0;
            byte b2 = (i < size) ? buf[i++] : 0;

            int mask = 0x3F;
            ar[a++] = ALPHABET[(b0 >> 2) & mask];
            ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
            ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
            ar[a++] = ALPHABET[b2 & mask];
        }
        switch(size % 3){
            case 1: ar[--a]  = '=';
            case 2: ar[--a]  = '=';
        }
        return new String(ar);
    }

    /**
     * Translates the specified Base64 string into a byte array.
     *
     * @param s the Base64 string (not null)
     * @return the byte array (not null)
     */
    public static byte[] decode(String s){
        int delta = s.endsWith( "==" ) ? 2 : s.endsWith( "=" ) ? 1 : 0;
        byte[] buffer = new byte[s.length()*3/4 - delta];
        int mask = 0xFF;
        int index = 0;
        for(int i=0; i< s.length(); i+=4){
            int c0 = toInt[s.charAt( i )];
            int c1 = toInt[s.charAt( i + 1)];
            buffer[index++]= (byte)(((c0 << 2) | (c1 >> 4)) & mask);
            if(index >= buffer.length){
                return buffer;
            }
            int c2 = toInt[s.charAt( i + 2)];
            buffer[index++]= (byte)(((c1 << 4) | (c2 >> 2)) & mask);
            if(index >= buffer.length){
                return buffer;
            }
            int c3 = toInt[s.charAt( i + 3 )];
            buffer[index++]= (byte)(((c2 << 6) | c3) & mask);
        }
        return buffer;
    } 

}

person chanjianyi    schedule 16.09.2014    source источник
comment
Что такое utob и btou?   -  person Mark Adler    schedule 16.09.2014


Ответы (2)


"w4tIw43DicOJL8OPL8OKSQEA" не является кодировкой Base-64 действительного необработанного потока дефляции. Так что мне кажется, что он не работает нормально. Я не могу точно сказать, что делает ваш код Javascript. Смотрите мои вопросы в комментариях к вашему вопросу.

Даже если бы это было так, ваш код Java ожидает оболочку zlib для данных выкачивания, тогда как код Javascript написан для создания и использования необработанных данных выкачки без оболочки. Чтобы заставить Java раздувать необработанные данные deflate, вам необходимо:

Inflater decompresser = new Inflater(true);

чтобы выбрать вариант nowrap.

person Mark Adler    schedule 16.09.2014
comment
На самом деле я тоже не знаю подробностей этого кода, поэтому, если забыть об этом случае, у вас есть какой-нибудь образец для сжатия строки в Javascript и распаковки в Java? - person chanjianyi; 17.09.2014
comment
Любой, кто застрял в этом вопросе, должен попробовать вариант nowrap. Это было именно то, чего мне не хватало. - person Hudson Pena Magalhães; 17.08.2015

Наконец, я нашел решение. Может быть, это не лучшее решение, но решить мою проблему.

хотя и с не очень хорошей производительностью.

используйте Javascript как на стороне клиента, так и на стороне сервера (движок Java js)..

Так что я могу сохранить результат таким же ..

person chanjianyi    schedule 26.09.2014