我使用 7zip 来计算文件夹(带有子文件夹)的哈希值,它有两个选项:包含或不包含文件名。
然而,在 Linux 版本的 7zip 上,哈希功能尚未实现。我尝试了不同的方法复制结果,但是这些方法都不会在 Linux 和 Windows 上产生相同的结果。
结果示例:
7za.exe h -scrcsha1 myfolder
在 Windows 上显示:
SHA1 for data: D54D3168B16BFEE600C3A77E848A2A1C1DBCBC59
SHA1 for data and names: BCE55085200581AD1774CC25AE065DE7DE60077D
,而在Linux上我有:
find . -type f -exec sha1sum "$PWD"/{} \; | sha1sum
ee44137f2462bdfea87ec824dab514f288ae3e6c -
或者
find . -type f | xargs sha1sum | sha1sum
8f971311a28bcdee36fab0ce87a892564622db40 -
所以我无法在一个平台上使用另一个平台的结果。
(我确实验证了单个文件的结果对于两个平台是相同的。)
答案1
仅运行以下命令不一定有效:
find . -type f | xargs sha512sum | sha512sum
您可能会遇到的问题是,报告的文件顺序find
在不同系统之间甚至在不同目录复制之间是不同的。
相反,尝试运行以下命令:
find . -type f | sort | xargs sha512sum | sha512sum
根据您的要求,可随意交换sha512sum
其他的 - 例如:md5sum
// sha1sum
。sha256sum
请注意,对于较大的目录树,这可能会变慢,在这种情况下,您可能更喜欢使用更复杂的脚本来遍历层次结构。
例子:
$ find . -type f | xargs sha512sum | sha512sum
097e56f6b751c1da15ce5b9dce853ffcc89e06e9cbe10a8dc0894dedb834d40dc4228c65e48bd53f136dd6a7700b0ab07e8e12e7100956db00b0d1b9ef0b9956 -
这包括最终哈希中的文件名和内容,但不包括元数据 - 修改时间、权限等......
请注意,您可以在 Windows 上使用“适用于 Linux 的 Windows 子系统find
“。我刚刚安装了它,这是一个轻松的体验,并且还让我意识到了报告的订购问题。
还要注意 Linux 与 Windows 上树中的符号链接是如何处理的。
答案2
不幸的是,似乎无法重现 7-zip 生成的文件夹的哈希值。
这是因为 7z 使用 FindNextFileW() 函数来枚举目录(7z-1900src/CPP/Windows/FileFind.cpp,第 198 行)。
函数返回值的顺序无法保证,并且可能与文件系统有关(根据https://docs.microsoft.com/zh-cn/windows/win32/api/fileapi/nf-fileapi-findnextfilew)。
所以如果您想实现一个独立于平台的目录哈希函数,您应该使用统一的排序函数。
答案3
由于 Linux 无法复制 7zip 校验和,而且我没有 nodeJS,因此我安装了“Windows Subsystem for Linux”来验证从 Windows 计算机到 Synology NAS 的文件夹复制。安装 WSL 非常简单,只需按照文档。
对于在 Windows 和 Linux 上实际生成相同哈希值的命令,我主要参考了如何计算目录的 MD5 校验和?,解释了如何在 Windows 和 Linux 之间对结果进行一致排序,以及如何不忽略空目录。一致排序是通过以下方式实现的LC_ALL=C
:
find . -type f -print0 | LC_ALL=C sort -z | xargs -r0 sha512sum | sha512sum
但是这不能处理空目录,所以这里有一个从其他答案复制的更完整的命令。它不用于-print0
降低复杂性,但 Windows 不允许在文件/文件夹名称中使用换行符和此类特殊字符,所以没什么大不了的。
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
最后,Synology 会创建额外的文件/文件夹用于索引,因此我还必须忽略索引文件-not -path
。这是我的最后一个命令,它在 WSL 中为我的 Windows 文件夹生成了相同的校验和,在 Synology SSH 中为复制的文件夹生成了相同的校验和:
dir=.; (find "$dir" -type f -not -path '*@eaDir*' -exec sha512sum {} +; find "$dir" -type d -not -path '*@eaDir*') | LC_ALL=C sort | sha512sum