为什么Java和Go的gzip会得到不同的结果

为什么Java和Go的gzip会得到不同的结果

本文介绍了为什么Java和Go的gzip会得到不同的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我的Java版本:

  string str =helloworld; 
ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream(str.length());
GZIPOutputStream localGZIPOutputStream = new GZIPOutputStream(localByteArrayOutputStream);
localGZIPOutputStream.write(str.getBytes(UTF-8));
localGZIPOutputStream.close();
localByteArrayOutputStream.close();
for(int i = 0; i< localByteArrayOutputStream.toByteArray()。length; i ++){
System.out.println(localByteArrayOutputStream.toByteArray()[i]);
}

输出结果为:

31
-117
8
0
0
0
0
0
0
0
-53
72
-51
-55
-55
47
-49
47
- 54
73
1
0
-83
32
-21
-7
10
0
0
0



然后Go版本:

  var gzBf bytes.Buffer 
gzSizeBf:= bufio.NewWriterSize(& gzBf,len(str))
gz:= gzip.NewWriter(gzSizeBf)
gz.Write([ ] byte(str))
gz.Flush()
gz.Close()
gzSizeBf.Flush()
GB:=(& gzBf).Bytes()
for i:= 0;我< LEN(GB); i ++ {
fmt.Println(GB [i])
}

输出:

31
139
8
0
0
9
110
136
0
255
202
72
205
201
201
47
207
47
202
73
1
0
0
0
255
255
1
0
0
255
255
173
32
235
249
10
0
0
0

为什么?

我认为这可能是由不同的字节读取方法引起的首先是这两种语言。但我注意到0不能转换为9.并且 [] byte 的大小是不同的。



我写错了代码?有没有办法让我的Go程序获得与Java程序相同的输出?



谢谢!

解决方案

通过,GZip文件头的结构为:

  + --- + --- + --- + --- + --- + --- + --- + --- + --- + --- + 
| ID1 | ID2 | CM | FLG | MTIME | XFL | OS | (more - >)
+ --- + --- + --- + --- + --- + --- + --- + --- + --- + - - +

查看您提供的输出,我们有:

  | Java |去
ID1 | 31 | 31
ID2 | 139 | 139
CM(压缩方式)| 8 | 8
FLG(标志)| 0 | 0
MTIME(修改时间)| 0 0 0 0 | 0 9 110 136
XFL(额外标志)| 0 | 0
OS(操作系统)| 0 | 255

因此,我们可以看到Go设置标题的修改时间字段,并设置操作系统转换为 255 (未知)而不是 0 (FAT文件系统)。在其他方面,它们表明该文件是以相同的方式压缩的。



通常,这些差异是无害的。如果您想确定两个压缩文件是否相同,那么您应该真正比较文件的解压缩版本。


Firstly, my Java version:

string str = "helloworld";
ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream(str.length());
GZIPOutputStream localGZIPOutputStream = new GZIPOutputStream(localByteArrayOutputStream);
localGZIPOutputStream.write(str.getBytes("UTF-8"));
localGZIPOutputStream.close();
localByteArrayOutputStream.close();
for(int i = 0;i < localByteArrayOutputStream.toByteArray().length;i ++){
    System.out.println(localByteArrayOutputStream.toByteArray()[i]);
}

and output is:

31-11780000000-5372-51-55-5547-4947-547310-8332-21-710000

Then the Go version:

var gzBf bytes.Buffer
gzSizeBf := bufio.NewWriterSize(&gzBf, len(str))
gz := gzip.NewWriter(gzSizeBf)
gz.Write([]byte(str))
gz.Flush()
gz.Close()
gzSizeBf.Flush()
GB := (&gzBf).Bytes()
for i := 0; i < len(GB); i++ {
    fmt.Println(GB[i])
}

output:

31139800911013602552027220520120147207472027310002552551002552551733223524910000

Why?

I thought it might be caused by different byte reading methods of those two languages at first. But I noticed that 0 can never convert to 9. And the sizes of []byte are different.

Have I written wrong code? Is there any way to make my Go program get the same output as the Java program?

Thanks!

解决方案

From RFC 1952, the GZip file header is structured as:

+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+

Looking at the output you've provided, we have:

                          |    Java |          Go
ID1                       |      31 |          31
ID2                       |     139 |         139
CM (compression method)   |       8 |           8
FLG (flags)               |       0 |           0
MTIME (modification time) | 0 0 0 0 | 0 9 110 136
XFL (extra flags)         |       0 |           0
OS (operating system)     |       0 |         255

So we can see that Go is setting the modification time field of the header, and setting the operating system to 255 (unknown) rather than 0 (FAT file system). In other respects they indicate that the file is compressed in the same way.

In general these sorts of differences are harmless. If you want to determine if two compressed files are the same, then you should really compare the decompressed versions of the files though.

这篇关于为什么Java和Go的gzip会得到不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 04:34