Wie erhält man unter Windows und Linux den gleichen Hash aus einem Ordner?

Wie erhält man unter Windows und Linux den gleichen Hash aus einem Ordner?

Ich habe 7zip verwendet, um den Hash eines Ordners (mit Unterordnern) zu berechnen, was mit zwei Optionen möglich ist, mit oder ohne Einbeziehung der Dateinamen.

In der Linux-Version von 7zip ist die Hash-Funktion jedoch nicht implementiert. Ich habe verschiedene ausprobiertMethodenum das Ergebnis zu duplizieren, aber keine dieser Methoden würde unter Linux und Windows dasselbe Ergebnis liefern.

Beispiele für Ergebnisse:

" 7za.exe h -scrcsha1 myfolder" unter Windows ergibt:

SHA1   for data:              D54D3168B16BFEE600C3A77E848A2A1C1DBCBC59
SHA1   for data and names:    BCE55085200581AD1774CC25AE065DE7DE60077D

, während ich unter Linux habe:

find . -type f -exec sha1sum "$PWD"/{} \; | sha1sum
ee44137f2462bdfea87ec824dab514f288ae3e6c  -

oder

find . -type f | xargs sha1sum | sha1sum
8f971311a28bcdee36fab0ce87a892564622db40  -

Ich kann die Ergebnisse einer Plattform also nicht auf einer anderen verwenden.

(Ich habe überprüft, dass das Ergebnis für eine einzelne Datei auf beiden Plattformen gleich ist.)

Antwort1

Das einfache Ausführen des folgenden Befehls funktioniert nicht unbedingt:

find . -type f | xargs sha512sum | sha512sum

Das Problem, mit dem Sie möglicherweise konfrontiert werden, besteht darin, dass die Reihenfolge der gemeldeten Dateien findvon System zu System oder sogar von Verzeichniskopie zu Verzeichniskopie unterschiedlich ist.

Versuchen Sie stattdessen, Folgendes auszuführen:

find . -type f | sort | xargs sha512sum | sha512sum

Sie können es gerne gegen ein anderes austauschen sha512sum, z. B.: md5sum/ sha1sum/, sha256sumje nach Ihren Anforderungen.

Beachten Sie, dass dies bei großen Verzeichnisbäumen langsam werden kann. In diesem Fall bevorzugen Sie möglicherweise ein komplexeres Skript zum Durchlaufen der Hierarchie.


Beispiel:

$ find . -type f | xargs sha512sum | sha512sum
097e56f6b751c1da15ce5b9dce853ffcc89e06e9cbe10a8dc0894dedb834d40dc4228c65e48bd53f136dd6a7700b0ab07e8e12e7100956db00b0d1b9ef0b9956  -

Dies schließt Dateinamen und Inhalte im endgültigen Hash ein, jedoch keine Metadaten – Änderungszeiten, Berechtigungen usw. …


Beachten Sie, dass Sie diese Dienstprogramme unter Windows verwenden können, indem Sie „Windows-Subsystem für Linux". Ich habe es gerade installiert, was völlig problemlos verlief und mir auch das Problem mit findder gemeldeten Reihenfolge bewusst gemacht hat.

Achten Sie auch darauf, wie symbolische Links in Ihrem Baum unter Linux im Vergleich zu Windows behandelt werden.

Antwort2

Leider scheint es unmöglich zu sein, den Hash eines von 7-Zip generierten Ordners zu reproduzieren.

Dies liegt daran, dass 7z die Funktion FindNextFileW() verwendet, um die Verzeichnisse aufzuzählen (7z-1900src/CPP/Windows/FileFind.cpp, Zeile 198).

Die Reihenfolge der Rückgabewerte der Funktion ist nicht garantiert und kann dateisystemabhängig sein (gemäßhttps://docs.microsoft.com/zh-cn/windows/win32/api/fileapi/nf-fileapi-findnextfilew).

Wenn Sie also eine plattformunabhängige Verzeichnis-Hashing-Funktion implementieren möchten, sollten Sie eine einheitliche Sortierfunktion verwenden.

Antwort3

Da Linux die 7zip-Prüfsumme nicht duplizieren kann und ich kein nodeJS habe, habe ich "Windows Subsystem for Linux" installiert, um eine Ordnerkopie von einem Windows-Computer auf ein Synology NAS zu überprüfen. Die Installation von WSL war ziemlich schmerzlos, folgen Sie einfachdie Dokumente.

Für einen Befehl, der tatsächlich den gleichen Hash sowohl unter Windows als auch unter Linux generierte, bezog ich mich hauptsächlich aufWie kann ich eine MD5-Prüfsumme eines Verzeichnisses berechnen?, in dem erklärt wird, wie Ergebnisse zwischen Windows und Linux konsistent sortiert werden und wie leere Verzeichnisse NICHT ignoriert werden. Eine konsistente Sortierung wird erreicht mit LC_ALL=C:

find . -type f -print0 | LC_ALL=C sort -z | xargs -r0  sha512sum | sha512sum

Das funktioniert aber nicht mit leeren Verzeichnissen, daher folgt hier ein vollständigerer Befehl, der aus der anderen Antwort kopiert wurde. Er -print0reduziert die Komplexität nicht, aber Windows erlaubt ohnehin keine Zeilenumbrüche und solche Sonderzeichen in Datei-/Ordnernamen, also keine große Sache.

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

Schließlich erstellt die Synology zusätzliche Dateien/Ordner für die Indizierung, sodass ich auch die Indexdateien mit ignorieren musste -not -path. Dies war mein letzter Befehl, der in WSL für meinen Windows-Ordner und in Synology SSH für den kopierten Ordner dieselbe Prüfsumme generierte:

dir=.; (find "$dir" -type f -not -path '*@eaDir*' -exec sha512sum {} +; find "$dir" -type d -not -path '*@eaDir*') | LC_ALL=C sort | sha512sum

verwandte Informationen