md5sum для больших файлов

md5sum для больших файлов

Контекст:

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

Вы можете создать такую ​​сумму:

FILE=four_gig_file.iso
SUM=$(head -c 1M "$FILE" | md5sum)
printf "%s *%s\n" ${SUM%-} "$FILE" >>test.md5

Как бы вы это проверили, если подпись первого мегабайта отличается от подписи всего файла?

Я видел, как это делается в других языках, но мне интересно, как это сделать вБаш. Я экспериментировал с различными md5sum -cкомбинациями труб и всего такого.


Вместо использования md5sum -c, вам придется пересчитывать хэши в новый файл, а затем «сравнивать» их?

Вы можете использовать

find /directory/path/ -type f -print0 | xargs -0 md5sum blah blah

для работы с большим количеством файлов.

P.S.:Rsync не вариант

ОБНОВЛЕНИЕ 2: Итак, как есть —

Используя head, find и md5sum; можно было бы довольно быстро создать файл из исходного каталога, а затем проверить его с помощью diff на другой стороне после вычисления на месте назначения. Есть ли умные однострочники или скрипты для этого?

решение1

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

Если вы хотите проверить целостность данных, вам лучше подойдет алгоритм CRC32. Он быстрее, чем MD5. Хотя и возможно подделать/изменить файл, чтобы он выглядел как имеющий правильную подпись CRC32, маловероятно, что случайные повреждения когда-либо сделают это.

Обновлять:

Вот хороший однострочный код для создания контрольной суммы md5 размером 1 мегабайт для каждого файла:

find ./ -type f -print0 | xargs -0 -n1 -I{} sh -c "echo '{}' >> output.md5 && head -c 1M '{}' | md5sum >> output.md5"

Замените md5sum на cksum, если вам так хочется. Обратите внимание, что я решил включить имя файла в вывод. Это потому, что строка имени файла не передается, когда вы не передаете md5sum весь файл.

решение2

Немного измененное решение/пример, использующее аргумент find -size для ограничения только файлов размером более 10 МБ и вычисляющее md5sum из первой и последней части файла размером 1 МБ.

find . -type f -a -size +10M -print0 | xargs -0 -n1 -I{} sh -c 'echo "$( (head -c 1M '{}'; tail -c 1M '{}' ) | md5sum) {} "'

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