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