Php's gzcompress in Java


Php's gzcompress in Java

我试图像php的gzcompression函数那样在Java中压缩字符串。但结果无法获得相同的字节数组。

我的php代码:

<?php
echo 'This is a test';
$compressed = gzcompress('This is a test');
echo '<br>';
for ($i=0; $i<strlen($compressed); $i++) {
    echo '['.$i.'] = '.ord($compressed[$i]).'<br>';
}
?>

结果:

这是一个测试

[0] = 120 
[1] = 156 
[2] = 11 
[3] = 201 
[4] = 200 
[5] = 44 
[6] = 86 
[7] = 0 
[8] = 162 
[9] = 68 
[10] = 133 
[11] = 146 
[12] = 212 
[13] = 226 
[14] = 18 
[15] = 0 
[16] = 36 
[17] = 115 
[18] = 4 
[19] = 246 

Java代码:

public class Main {
    public static byte[] compressString(String uncompressedString) throws IllegalArgumentException, IllegalStateException {
        try {
            byte[] utfEncodedBytes = uncompressedString.getBytes();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {
                gzipOutputStream.write(utfEncodedBytes);
                gzipOutputStream.finish();
            }
            return baos.toByteArray();
        } catch (Exception e) {
            throw new IllegalStateException("GZIP compression failed: " + e, e);
        }
    }
    public static void main(String[] args) {
        String input = "This is a test";
        System.out.println("Input:  " + input);
        byte[] compressed = compressString(input);
        for (int i = 0; i < compressed.length; i++) {
            System.out.println("[" + i + "] = " + (compressed[i] & 0xFF));
        }
    }
}

结果:

输入:这是一个测试

[0] = 31 
[1] = 139 
[2] = 8 
[3] = 0 
[4] = 0 
[5] = 0 
[6] = 0 
[7] = 0 
[8] = 0 
[9] = 0 
[10] = 11 
[11] = 201 
[12] = 200 
[13] = 44 
[14] = 86 
[15] = 0 
[16] = 162 
[17] = 68 
[18] = 133 
[19] = 146 
[20] = 212 
[21] = 226 
[22] = 18 
[23] = 0 
[24] = 50 
[25] = 159 
[26] = 122 
[27] = 192 
[28] = 14
[29] = 0 
[30] = 0 
[31] = 0 

压缩数组的中间部分是相同的。但它们在开始和结束时是不同的。

gzcompression函数的文档特别指出它使用的压缩算法是zlib,也就是

与gzip压缩不同,后者包括一些头数据。有关gzip压缩,请参阅gzencoder()。

Java的GZIPOutputStream可以进行正确的gzip压缩,包括正确的头。DeflaterOutputStream在没有gzip标头的情况下进行纯放气,这可能更接近您所追求的,或者有JZlib等第三方解决方案。

根据RFChttp://www.gzip.org/zlib/rfc-gzip.html

它声明文件的开头应包含。

ID1(标识1)ID2(身份识别2)它们具有固定值ID1=31(0x1f,''037),ID2=139(0x8b,''213),以将文件标识为gzip格式。

CM(压缩方法)这标识了文件中使用的压缩方法。保留CM=0-7。CM=8表示"deflate"压缩方法,这是gzip通常使用的方法,在其他地方也有记录。

所以前三个字节应该是31139,8。第四个字节应该是0-31之间的值(使用0到4位,保留5、6和7位)。我怀疑您在PHP中看到的输出不是gz格式。