1. 程式人生 > >java與.net gzip結果不一致

java與.net gzip結果不一致

一個字串通過.net gzip壓縮後,通過java解析,發現結果並不一致,將得到的位元組陣列轉為16進位制字串後發現,java gzip和.net gzip得到的前10個位元組不一致。這10個位元組是gzip固定格式,如下:

java:1F8B0800000000000000

.net:1F8B0800000000000400

所以,在處理的時候將其替換掉就好了。我之前的需求是將物件壓縮後,通過base64儲存,程式碼如下(序列化的方法自己寫下就好了):

public class GzipCompatibleNetUtil {
    private static final String GZIP_NET = "1F8B0800000000000400";
    private static final String GZIP_JAVA = "1F8B0800000000000000";
    private static final String CODE_FORMAT = "UTF-8";


    /***
     * token 先gzip壓縮,再轉base64
     * @param t 物件
     * @param <T> 物件型別
     * @return base64編碼字串
     */

    protected <T> String objectToBase64(T t) {
        String jsonStr = ";
        return compressString(jsonStr);
    }

    protected <T> T base64ToObject(String base64Str, Class<T> tClass) {
        try {
            String jsonStr = decompressString(base64Str);
            JsonSerializer serializer = new JsonSerializer();
            return serializer.deserialize(jsonStr, tClass);
        } catch (Exception e) {
            return null;
        }
    }


    private String compressString(String str) {
        String compressString = "";
        try {
            byte[] compressBeforeByte = str.getBytes(CODE_FORMAT);
            byte[] compressAfterByte = compress(compressBeforeByte);

            String compressAfterStr = byteToHexString(compressAfterByte);
            String finalStr = compressAfterStr.replaceFirst(GZIP_JAVA, GZIP_NET);
            byte[] finalByte = hexStringToBytes(finalStr);

            compressString = Base64.encodeBase64String(finalByte);
        } catch (Exception e) {

        }
        return compressString;
    }

    private static byte[] compress(byte[] data) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(data);
            gzip.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return out.toByteArray();
    }

    private String decompressString(String str) {
        String compressString = "";
        try {
            byte[] compressBeforeByte = Base64.decodeBase64(str);

            String compressAfterStr = byteToHexString(compressBeforeByte);
            String finalStr = compressAfterStr.replaceFirst(GZIP_NET, GZIP_JAVA);
            byte[] finalByte = hexStringToBytes(finalStr);

            byte[] compressAfterByte = decompress(finalByte);
            compressString = new String(compressAfterByte, CODE_FORMAT);

        } catch (Exception e) {

        }
        return compressString;
    }

    private static byte[] decompress(byte[] data) {
        if (data == null || data.length == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(data);
        try {
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return out.toByteArray();

    }

    private static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    private static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || "".equals(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}