【问题标题】:"java.util.zip.DataFormatException: incorrect header check" when deflate in JavaScript then inflate in Java“java.util.zip.DataFormatException:不正确的标头检查”在 JavaScript 中放气然后在 Java 中膨胀
【发布时间】:2014-11-09 19:52:25
【问题描述】:

我的页面中有大数据,需要发布到服务器。

所以我使用https://github.com/dankogai/js-deflate 来压缩大数据。

似乎工作正常。

helloworld -> 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>

所以我想通过将 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;
    } 

}

【问题讨论】:

  • 什么是utobbtou

标签: java javascript base64 deflate inflate


【解决方案1】:

最后,我找到了解决方案。也许这不是最好的解决方案,但解决我的问题。

虽然表现不佳。

在客户端和服务器端都使用 Javascript(Java js 引擎)..

所以我可以保持结果相同..

【讨论】:

    【解决方案2】:

    “w4tIw43DicOJL8OPL8OKSQEA”不是有效原始 deflate 流的 Base-64 编码。所以它对我来说似乎并不正常。我真的不知道你的 Javascript 代码在做什么。在你的问题的 cmets 中查看我的问题。

    即使是这样,您的 Java 代码也期望对 deflate 数据使用 zlib 包装器,而编写 Javascript 代码是为了在没有包装器的情况下生成和使用原始 deflate 数据。要让 Java 对原始 deflate 数据进行膨胀,您需要:

    Inflater decompresser = new Inflater(true);
    

    选择nowrap 选项。

    【讨论】:

    • 其实我也不知道这段代码做的细节,所以如果忘记这个案例,你有什么例子可以让我用Javascript压缩字符串并用Java解压吗?
    • 任何陷入这个问题的人都应该尝试“nowrap”选项。这正是我所缺少的。
    猜你喜欢
    • 2021-08-31
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2011-11-24
    • 1970-01-01
    相关资源
    最近更新 更多