压缩文件包含相同的文件但哈希值不同?

16

我使用PHP创建了数百个文件夹和文本文件,然后将它们添加到一个zip归档文件中。

这一切都很正常,但是如果我再次使用相同的文件夹和文件创建另一个zip归档文件,新的归档文件将与第一个归档文件具有不同的哈希值。如果我使用WinRAR而不是PHP来创建归档文件,情况也是如此。

只有当我压缩通过PHP创建的文件时,它们才显示不同的哈希值,但打开正常。

非常奇怪,有人能解释一下吗?

谢谢


我猜可能是压缩文件中的创建时间戳不同? - Orn Kristjansson
@orn 文件未被更改,我可以连续创建两个压缩文件,结果将是相同的。 - arbme
@arbme,他的意思是也许在“created”压缩文件中有一个时间戳。由于它们不是同时创建的,所以它们会不同。 - Jonathon Reinhart
我以为文件的时间戳不会被计入,只考虑文件内容。但事实证明,即使内容相同,如果你没有按照相同的顺序添加文件,你将得到不同的哈希值。 - arbme
3个回答

20
Zip文件是不确定性的。为了解决这个zip问题(例如,当您拥有CI并且需要更新AWS Lambda时,并且不想每次都更新它,而只在确实更改了某些内容时才更新),我使用了这篇文章:https://medium.com/@pat_wilson/building-deterministic-zip-files-with-built-in-commands-741275116a19
find . -exec touch -t "$(git ls-files -z . | \
  xargs -0 -n1 -I{} -- git log -1 --date=format:"%Y%m%d%H%M" --format="%ad" '{}' | \
  sort -r | head -n 1)" '{}' +
zip -rq -D -X -9 -A --compression-method deflate dest.zip sources...

这正是我的使用情况。非常感谢! - Shlublu
帮助很多的惊人文章 - rpf3

8

这些文件肯定存在一些差异。如果它们的长度不完全相同,那么哈希值也会不同。你可以使用类似于 Hex Workshop 的十六进制比较编辑器,来查看具体的差异。

以下是我想到的可能性:

  1. 如 @orn 所提到的,您使用的 zip 格式中可能有时间戳(不确定)。
  2. 添加到存档中的文件顺序可能不同(取决于您如何选择它们/构建源数组)。

2
这是错误的,除非强制内部创建和修改时间,否则zip文件将始终不同。https://dev59.com/Tmkw5IYBdhLWcg3wrsrn - Léo Germond
告诉我我的答案具体哪里有问题。 - Jonathon Reinhart

0
您可以考虑使用deterministic_zip来解决这个问题,根据它的文档:
有三个技巧来构建确定性zip:
文件必须按相同的顺序添加到zip中。目录迭代顺序可能因机器而异,导致不同的zip。deterministic_zip在将文件添加到zip存档之前对所有文件进行排序。
zip中的文件必须具有一致的时间戳。如果我将一个目录共享到另一台机器上,尽管具有相同的内容,但单个文件的时间戳可能会有所不同。为了实现时间戳的一致性,deterministic_zip将所有添加的文件的时间戳设置为2019-01-01 00:00:00。
zip中的文件必须具有一致的权限。文件权限看起来像-rw-r--r--,表示所有用户都可以读取该文件,只有拥有该文件的用户才能写入该文件。类似地,可执行文件可能具有如下权限:-rwxr-xr-x或-rwx------。deterministic_zip将添加到存档中的所有文件的权限设置为-r--r--r--或-r-xr-xr-x。只有当运行deterministic_zip的用户对该文件具有执行访问权限时,才会使用后者。
注意:deterministic_zip 不会修改或更新其添加到存档中的任何文件的时间戳。上述使用的技术仅适用于 deterministic_zip 创建的存档内文件的副本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接