Как получить одинаковый хэш папки в Windows и Linux?

Как получить одинаковый хэш папки в Windows и Linux?

Я использовал 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  -

Сюда входят имена файлов и содержимое в конечном хэше, но не входят метаданные — время изменения, разрешения и т. д.


Обратите внимание, что вы можете использовать эти утилиты в Windows, используя «Подсистема Windows для Linux". Я только что установил его, что оказалось безболезненным опытом, и это также заставило меня осознать проблему с 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

Связанный контент