首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定GZIPOutputStream行为

确定GZIPOutputStream行为
EN

Stack Overflow用户
提问于 2020-02-16 03:31:23
回答 1查看 61关注 0票数 0

下面的代码为两个字符串生成确定性(shasum相同)的文件。

代码语言:javascript
复制
    try(
            FileOutputStream fos = new FileOutputStream(saveLocation);
            GZIPOutputStream zip = new GZIPOutputStream(fos, GZIP_BUFFER_SIZE);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zip, StandardCharsets.UTF_8));
            ){
        writer.append(str);
    }

产生:

代码语言:javascript
复制
a.gz f0200d53f7f9b35647b5dece0146d72cd1c17949

但是,如果我在命令行中获取该文件并重压缩它,则会产生不同的结果

代码语言:javascript
复制
> gunzip -n a.gz ;gzip -n a ; shasum a.gz 

50f478a9ceb292a2d14f1460d7c584b7a856e4d9  a.gz

如何使用/usr/bin/gzip和gunzip使其与原始的sha匹配?

EN

回答 1

Stack Overflow用户

发布于 2020-02-16 09:52:23

我认为问题可能出在Gzip文件头。

Gzip格式的

  • 提供了在文件头中包含文件名和文件时间戳的规定。(我看到您在解压缩和重新压缩时使用的是-n ...这在这里可能是正确的。)

  • Gzip格式还在报头中包含了一个“操作系统id”。这应该用来标识源文件系统类型;例如,0表示FAT,3表示UNIX,依此类推。

这两种方法中的任何一种都可能导致Gzip文件的不同,从而导致不同的散列。

如果我要自己解决这个问题,我会首先使用cmp来查看压缩文件的差异,然后使用od来确定差异是什么。请参考Gzip文件格式规范,了解差异的含义:

  • RFC 1952 - GZIP文件格式规范版本4.3
  • Wikipedia's gzip页。

如何使用gzipgunzip使其与原始SHA匹配?

假设不同之处在于操作系统id,我不认为使用gzipgunzip命令可以解决这个问题。

我看过Java11中GZIPOutputStream的源代码,结果并不乐观。

  • 它正在将时间戳硬连线到零。
  • 它正在将操作系统标识符硬连线到零(这应该表示FAT)。

硬连接是在private方法中,几乎不可能通过子类化或反射来“修复”。您可以复制代码并以这种方式修复它,但随后您必须无限期地维护变体GZIPOutputStream类。

(我会考虑更改应用程序...或者其他什么..。这样我就不需要校验和是一样的。你还没有说你为什么要这样做。它仅用于测试目的,请尝试寻找不同的方法来实现测试。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60242386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档