關於Java的GZIP壓縮與.net C#的GZIP壓縮的差異

sunny518發表於2016-12-29

今天在做一個java專案的時候,需要獲取.net壓縮後的xml,進行解壓縮展示。

試了很多次,居然發現java gzip無法解壓縮.net壓縮後的密文,真是奇恥大辱,經過多倫分析,發現.net GZIP壓縮和java GZIP壓縮存在差異。

主要的差異在於,.net GZIP在前後4個位元組都寫入了長度,而java GZIP只在尾部追加長度,就這麼一點點差別浪費了大半天時間,不多說上程式碼。

 

首先是java壓縮:

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		String str="hello world";
		
		byte[ ] bytes=str.getBytes();
		System.out.println("壓縮前長度:"+bytes.length);
		byte[ ] gzipBytes=gzip(bytes);
		System.out.println("壓縮後長度:"+gzipBytes.length);
		System.out.println("壓縮後:"+byteToHexString(gzipBytes));
		byte[ ] unGzipBytes=unGzip(gzipBytes);
		System.out.println("解壓後:"+byteToHexString(unGzipBytes));
	}

結果顯示:

壓縮前長度:11
壓縮後長度:31
壓縮後:1F8B0800000000000000CB48CDC9C95728CF2FCA49010085114A0D0B000000
解壓後:68656C6C6F20776F726C64

上面的1F8B0800000000000000是10個位元組的固定GZIP格式,最後8個位元組表示壓縮前的資料長度。

 

.net gzip

class Program
    {
        static void Main(string[] args)
        {
            //要壓縮的字串
            string data = "hello world";

            byte[] buffer = System.Text.UTF8Encoding.UTF8.GetBytes(data);
            //壓縮後的byte陣列
            byte[] compressedbuffer = null;
            //Compress buffer,壓縮快取
            MemoryStream ms = new MemoryStream();
            using (GZipStream zs = new GZipStream(ms, CompressionMode.Compress, true))
            {
                zs.Write(buffer, 0, buffer.Length);
      

            }

            //只有GZipStream在Dispose後調應對應MemoryStream.ToArray()所得到的Buffer才是我們需要的結果
            compressedbuffer = ms.ToArray();
            //將壓縮後的byte陣列basse64字串
            string hex =  BitConverter.ToString(compressedbuffer); 
            Console.WriteLine(hex);
            
        }
    }

 

壓縮後:0B0000001F8B0800000000000000CB48CDC9C95728CF2FCA49010085114A0D0B000000

可以清楚的看到.net壓縮後,前後4個位元組是一樣的,都是長度。

 

那java端怎麼讀取呢,很簡單,去掉那4個位元組即可

byte[] src = Base64Util.decode(str_base);
byte[] result = new byte[src.length-4];
System.arraycopy( src, 4, result, 0, result.length );


反過來c#端如果解析java端GZIP的呢,這個不用說了吧,加上4個位元組。

 

感謝拍馬屁的部落格指引 :http://blog.csdn.net/qq_18870023/article/details/52189300#

相關文章