Конечно, должен быть способ сделать это легко!
Я пробовал приложения командной строки Linux, такие как sha1sum
и, md5sum
но они, похоже, могут вычислять только хэши отдельных файлов и выводить список значений хэшей, по одному для каждого файла.
Мне нужно сгенерировать единый хеш для всего содержимого папки (а не только для имен файлов).
Я бы хотел сделать что-то вроде
sha1sum /folder/of/stuff > singlehashvalue
Изменить: чтобы уточнить, мои файлы находятся на нескольких уровнях в дереве каталогов, они не все находятся в одной корневой папке.
Ответы:
Один из возможных способов:
Если есть целое дерево каталогов, вам, вероятно, лучше использовать find и xargs. Одна из возможных команд была бы
И, наконец, если вам также нужно учитывать разрешения и пустые каталоги:
(find path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum; find path/to/folder \( -type f -o -type d \) -print0 | sort -z | \ xargs -0 stat -c '%n %a') \ | sha1sum
Аргументы
stat
заставят его напечатать имя файла, а затем его восьмеричные разрешения. Эти два поиска будут выполняться один за другим, что приведет к удвоению количества операций ввода-вывода на диске: первое обнаружит все имена файлов и вычислит контрольную сумму содержимого, второе обнаружит все имена файлов и каталогов, имя и режим печати. Список «имен файлов и контрольных сумм», за которым следуют «имена и каталоги с разрешениями», затем будет суммирован для получения меньшей контрольной суммы.источник
find ./folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
/
наpath/to/folder
бит.Используйте средство обнаружения вторжений в файловую систему, например помощник .
хэш tar-мяч каталога:
tar cvf - /path/to/folder | sha1sum
Кодируйте что-нибудь самостоятельно, например, vatine's oneliner :
find /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
источник
git config --local core.fileMode false
этого избежать, вы должны решить проблему, прежде чем совершать какие-либо действия . Не знаю, есть ли еще подобные предостережения.Ты можешь сделать
tar -c /path/to/folder | sha1sum
источник
--mtime
опцию следующим образом:tar -c /path/to/folder --mtime="1970-01-01" | sha1sum
.Если вы просто хотите проверить, не изменилось ли что-то в папке, я бы порекомендовал это:
Он просто предоставит вам хэш вывода ls, который содержит папки, подпапки, их файлы, их временные метки, размер и разрешения. Практически все, что вам нужно, чтобы определить, изменилось ли что-то.
Обратите внимание, что эта команда не будет генерировать хеш для каждого файла, но именно поэтому она должна быть быстрее, чем при использовании find.
источник
Надежный и чистый подход
Это то, что у меня в голове, любой, кто потратил некоторое время на работу над этим, практически поймал бы другие ловушки и угловые случаи.
Вот инструмент , очень мало использующий память, который подходит для большинства случаев, может быть немного грубоват, но оказался весьма полезным.
Пример использования и вывода
dtreetrawl
.Фрагмент удобного для человека вывода:
источник
Если вы просто хотите хэшировать содержимое файлов, игнорируя имена файлов, вы можете использовать
cat $FILES | md5sum
При вычислении хэша убедитесь, что файлы расположены в том же порядке:
cat $(echo $FILES | sort) | md5sum
Но у вас не может быть каталогов в вашем списке файлов.
источник
Еще один инструмент для этого:
http://md5deep.sourceforge.net/
Как это звучит: как md5sum, но также рекурсивно, плюс другие функции.
источник
Если это репозиторий git, и вы хотите игнорировать любые файлы в нем
.gitignore
, вы можете использовать это:git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1
У меня это хорошо работает.
источник
Для этого есть скрипт на Python:
http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/
Если вы измените имена файла без изменения их алфавитного порядка, хеш-скрипт не обнаружит его. Но если вы измените порядок файлов или содержимого любого файла, запуск скрипта даст вам другой хэш, чем раньше.
источник
Мне пришлось проверять весь каталог на предмет изменений в файлах.
Но без учета временных меток и прав собственности на каталоги.
Задача - получить одинаковую везде сумму, если файлы идентичны.
В том числе размещены на других машинах, независимо от чего-либо, кроме файлов или изменений в них.
md5sum * | md5sum | cut -d' ' -f1
Он генерирует список хэшей по файлам, а затем объединяет эти хэши в один.
Это намного быстрее, чем метод tar.
Для большей конфиденциальности в наших хэшах мы можем использовать sha512sum по тому же рецепту.
sha512sum * | sha512sum | cut -d' ' -f1
Хеши также идентичны везде, где используется sha512sum, но нет известного способа отменить его.
источник
sha256sum /tmp/thd-agent/* | sort
это то, что я пытаюсь сделать для надежного упорядочивания, а затем просто хэширую это.ls -r | sha256sum
?Попробуйте сделать это в два этапа:
Вот так:
# for FILE in `find /folder/of/stuff -type f | sort`; do sha1sum $FILE >> hashes; done # sha1sum hashes
Или сделать все сразу:
# cat `find /folder/of/stuff -type f | sort` | sha1sum
источник
for F in 'find ...' ...
не работает, когда в именах есть пробелы (что в наши дни всегда так).Я бы перенаправил результаты для отдельных файлов
sort
(чтобы предотвратить простое переупорядочение файлов для изменения хэша) вmd5sum
илиsha1sum
, в зависимости от того, что вы выберете.источник
Для этого я написал сценарий Groovy:
import java.security.MessageDigest public static String generateDigest(File file, String digest, int paddedLength){ MessageDigest md = MessageDigest.getInstance(digest) md.reset() def files = [] def directories = [] if(file.isDirectory()){ file.eachFileRecurse(){sf -> if(sf.isFile()){ files.add(sf) } else{ directories.add(file.toURI().relativize(sf.toURI()).toString()) } } } else if(file.isFile()){ files.add(file) } files.sort({a, b -> return a.getAbsolutePath() <=> b.getAbsolutePath()}) directories.sort() files.each(){f -> println file.toURI().relativize(f.toURI()).toString() f.withInputStream(){is -> byte[] buffer = new byte[8192] int read = 0 while((read = is.read(buffer)) > 0){ md.update(buffer, 0, read) } } } directories.each(){d -> println d md.update(d.getBytes()) } byte[] digestBytes = md.digest() BigInteger bigInt = new BigInteger(1, digestBytes) return bigInt.toString(16).padLeft(paddedLength, '0') } println "\n${generateDigest(new File(args[0]), 'SHA-256', 64)}"
Вы можете настроить использование, чтобы избежать печати каждого файла, изменить дайджест сообщения, удалить хеширование каталога и т. Д. Я проверил его на тестовых данных NIST, и он работает, как ожидалось. http://www.nsrl.nist.gov/testdata/
источник
Вы можете
sha1sum
сгенерировать список хеш-значений, а затемsha1sum
этот список снова, это зависит от того, что именно вы хотите выполнить.источник
Вот простой и короткий вариант в Python 3, который отлично работает для файлов небольшого размера (например, исходное дерево или что-то в этом роде, где каждый файл индивидуально может легко поместиться в ОЗУ), игнорируя пустые каталоги, на основе идей из других решений:
import os, hashlib def hash_for_directory(path, hashfunc=hashlib.sha1): filenames = sorted(os.path.join(dp, fn) for dp, _, fns in os.walk(path) for fn in fns) index = '\n'.join('{}={}'.format(os.path.relpath(fn, path), hashfunc(open(fn, 'rb').read()).hexdigest()) for fn in filenames) return hashfunc(index.encode('utf-8')).hexdigest()
Это работает так:
Вы можете передать другую хеш-функцию в качестве второго параметра, если SHA-1 вам не подходит.
источник
Пока что самый быстрый способ сделать это - использовать tar. А с помощью нескольких дополнительных параметров мы также можем избавиться от разницы, вызванной метаданными.
Чтобы использовать tar для хеширования каталога, нужно убедиться, что вы отсортировали путь во время tar, иначе он всегда будет другим.
игнорировать время
Если вас не волнует время доступа или время изменения, также используйте что-то вроде,
--mtime='UTC 2019-01-01'
чтобы убедиться, что все временные метки одинаковы.игнорировать право собственности
Обычно нам нужно добавить,
--group=0 --owner=0 --numeric-owner
чтобы унифицировать метаданные владельца.игнорировать некоторые файлы
использовать
--exclude=PATTERN
источник