Linux: вычислить один хэш для данной папки и содержимого?

Конечно, должен быть способ сделать это легко!

Я пробовал приложения командной строки linux sha1sum & md5sum, но они, похоже, способны вычислять хэши отдельных файлов и выводить список хеш-значений, по одному для каждого файла.

Мне нужно создать единый хеш для всего содержимого папки (а не только имен файлов).

Я хотел бы сделать что-то вроде

sha1sum /folder/of/stuff > singlehashvalue 

Изменить: чтобы уточнить, мои файлы находятся на нескольких уровнях в дереве каталогов, они не все находятся в одной корневой папке.

11 Solutions collect form web for “Linux: вычислить один хэш для данной папки и содержимого?”

Один из возможных способов:

 sha1sum path / to / folder / * |  sha1sum

Если есть целое дерево каталогов, вам, вероятно, лучше использовать find и xargs. Одна из возможных команд

 find path / to / folder -type f -print0 |  xargs -0 sha1sum |  sha1sum

Edit : Хорошая точка, это, вероятно, хорошая вещь, чтобы отсортировать список файлов, так что:

 find path / to / folder -type f -print0 |  sort -z |  xargs -0 sha1sum |  sha1sum

И, наконец, если вам также необходимо учитывать разрешения и пустые каталоги:

 (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 приведут к тому, что он напечатает имя файла, а затем его восьмеричные разрешения. Два находок будут запускаться один за другим, что приведет к удвоенному объему дискового ввода-вывода, первое обнаружение всех имен файлов и контрольное совмещение содержимого, второе обнаружение всех имен файлов и каталогов, имени печати и режима. Список «имен файлов и контрольных сумм», за которыми следуют «имена и каталоги с разрешениями», затем будет контрольной суммой для меньшей контрольной суммы.

  • Зафиксируйте каталог git, используйте хеш-код фиксации. См. Метастор для способа управления разрешениями.

  • Используйте средство обнаружения вторжений файловой системы, например, помощника .

  • хэш-тар-файл каталога:

    tar cvf – / путь / в / папка | sha1sum

  • Код что-то себе, например, ватине oneliner :

    find / path / to / folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum

Что случилось с tar -c /path/to/folder | sha1sum tar -c /path/to/folder | sha1sum ?

Если вы просто хотите хешировать содержимое файлов, игнорируя имена файлов, вы можете использовать

 cat $FILES | md5sum 

Удостоверьтесь, что у вас есть файлы в том же порядке при вычислении хэша:

 cat $(echo $FILES | sort) | md5sum 

Но вы не можете иметь каталоги в своем списке файлов.

Для этого есть скрипт python:

http://code.activestate.com/recipes/576973-getting-the-sha-1-or-md5-hash-of-a-directory/

Если вы измените имена файла без изменения их алфавитного порядка, хеш-скрипт не обнаружит его. Но если вы измените порядок файлов или содержимое любого файла, запуск скрипта даст вам другой хеш, чем раньше.

Если вы просто хотите проверить, изменилось ли что-то в папке, я бы рекомендовал следующее:

 ls -alR --full-time /folder/of/stuff | sha1sum 

Он просто даст вам хэш вывода ls, который содержит папки, подпапки, их файлы, их метку времени, размер и разрешения. Почти все, что вам нужно, чтобы определить, изменилось ли что-то.

Обратите внимание, что эта команда не генерирует хэш для каждого файла, но поэтому она должна быть быстрее, чем при использовании find.

Я буду передавать результаты для отдельных файлов через sort (чтобы предотвратить простое переупорядочение файлов для изменения хэша) в md5sum или sha1sum , в зависимости от того, что вы выберете.

Еще один инструмент для достижения этого:

http://md5deep.sourceforge.net/

Как это звучит: например, md5sum, но также рекурсивный, а также другие функции.

Я написал сценарий 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/

 gary-macbook:Scripts garypaduana$ groovy dirHash.groovy /Users/garypaduana/.config .DS_Store configstore/bower-github.yml configstore/insight-bower.json configstore/update-notifier-bower.json filezilla/filezilla.xml filezilla/layout.xml filezilla/lockfile filezilla/queue.sqlite3 filezilla/recentservers.xml filezilla/sitemanager.xml gtk-2.0/gtkfilechooser.ini a/ configstore/ filezilla/ gtk-2.0/ lftp/ menus/ menus/applications-merged/ 79de5e583734ca40ff651a3d9a54d106b52e94f1f8c2cd7133ca3bbddc0c6758 

Попробуйте сделать это в два этапа:

  1. создать файл с хэшами для всех файлов в папке
  2. hash этот файл

Вот так:

 # 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 

Вы можете sha1sum генерировать список хэш-значений, а затем sha1sum что список снова, это зависит от того, что именно вы хотите достичь.

Python - лучший язык программирования в мире.