我使用 7zip 來計算資料夾(帶有子資料夾)的雜湊值,它可以透過兩個選項來完成,包括或不包括檔案名稱。
然而,在 7zip 的 Linux 版本上,哈希功能並未實現。我嘗試了不同的方法複製結果,但這些方法都不會在 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 -
這包括最終哈希中的檔案名稱和內容,但不包括元資料 - 修改時間、權限等...
請注意,您可以透過使用“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