Java/zip:为什么.jar文件是非确定性创建的?

Syn*_*r0r 12 java zip

我从未真正研究过它,但现在我意识到我无法轻松构建两个相同的.jar文件.

我的意思是,如果我构建两次,没有改变任何东西,我得到完全相同的大小但.jar的校验和不同.

于是我赶紧跑了一些测试(基本解压,排序-n -k 5 "荷兰国际集团,然后DIFF "荷兰国际集团)看到所有文件里面将.jar是相同的,但该.jar是不同的.

所以我用一个简单的.zip文件做了测试,发现了这个:

... $ zip 1.zip a.txt
... $ zip 2.zip a.txt
... $ ls -l ?.zip
-rw-rw-r-- 1 webinator webinator 147 2010-07-21 13:09 1.zip
-rw-rw-r-- 1 webinator webinator 147 2010-07-21 13:09 2.zip
Run Code Online (Sandbox Code Playgroud)

(完全相同的.zip文件大小)

... $ sha1sum ?.zip
db99f6ad5733c25c0ef1695ac3ca3baf5d5245cf  1.zip
eaf9f0f92eb2ac3e6ac33b44ef45b170f7984a91  2.zip
Run Code Online (Sandbox Code Playgroud)

(不同的SHA-1总和,让我们看看为什么)

$ hexdump 1.zip -C > 1.txt

$ hexdump 2.zip -C > 2.txt

$ diff 1.txt 2.txt 
3c3
< 00000020  74 78 74 55 54 09 00 03  ab d4 46 4c*4e*d5 46 4c  |txtUT.....FLN.FL|
---
> 00000020  74 78 74 55 54 09 00 03  ab d4 46 4c*5d*d5 46 4c  |txtUT.....FL].FL|
Run Code Online (Sandbox Code Playgroud)

解压缩两个zip文件肯定会返回我们唯一的文件.

问题:为什么?(我会自己回答)

Syn*_*r0r 6

(回答自己)这是因为.zip文件格式在其标题中保存了创建和修改时间.

如果你真的想要创建两个相同的.zip(或.jar),你必须让第二个认为它与第一个完全同时创建/修改.

  • 我认为你把确定性与相同的混淆......它们不一样.确定性意味着每次以相同的方式构造,而不是必需的相同字节.您可以轻松地对文件执行二进制差异,并查看所有已更改的是时间戳(这是我们的主要客户之一必须执行的操作,以便将新的依赖项检入其dep-repo ...并且这对他们来说很难,但他们这样做是因为他们确实需要保证这些具有不同散列的文件是相同的). (2认同)