← Весь справочник

Контрольные суммы

sha256sum, md5sum и родственники — посчитать хеш, проверить файлы по списку, почему MD5 не для защиты

Контрольная сумма (хеш) — короткая строка, которая меняется при изменении хотя бы одного байта файла. По ней проверяют, что файл скачался целиком и не подменён, и находят изменившиеся файлы. В coreutils для каждого алгоритма своя команда с одинаковыми опциями: sha256sum, sha512sum, sha1sum, md5sum, b2sum.

Синтаксис

sha256sum [опции] [файл…]        # посчитать
sha256sum -c [опции] список      # проверить по списку

Без файла (или с -) читает stdin.

Формат вывода

5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03  a.txt

Хеш в шестнадцатеричном виде, два пробела, имя файла. Если между ними * вместо второго пробела (… *a.txt) — файл читался в «бинарном режиме»; в Linux разницы нет. Такие строки, сохранённые в файл, и есть список для -c. Для stdin вместо имени печатается -.

Опции при подсчёте

ОпцияЧто делает
--tagформат BSD: SHA256 (a.txt) = … — сразу видно алгоритм
-b / -tбинарный / текстовый режим; в GNU/Linux результат одинаковый, меняется только * в выводе
-zзавершать строки нулевым байтом вместо \n

Опции при проверке (-c)

ОпцияЧто делает
-c списокдля каждой строки пересчитать хеш файла и сравнить: имя: OK или имя: FAILED
--quietне печатать OK, только ошибки
--statusничего не печатать; результат — только код выхода
--ignore-missingмолча пропускать файлы, которых нет на диске
--strictненулевой код выхода, если в списке есть кривые строки
-wпредупреждать о каждой кривой строке с номером

Код выхода -c: 0 — всё совпало, 1 — есть несовпадения, отсутствующие файлы или ошибки чтения.

Алгоритмы

КомандаДлина хешаДля чего годится
md5sum32 hex-символабыстрая проверка от случайной порчи; не для защиты
sha1sum40устаревший, коллизии найдены; встречается в старых списках и в git
sha256sum64стандарт по умолчанию для проверки загрузок
sha512sum128то же семейство SHA-2, длиннее
b2sum128BLAKE2b: быстрый и стойкий

Примеры

# хеш файла
sha256sum archive.tar.gz

# только хеш, без имени
sha256sum archive.tar.gz | cut -d' ' -f1

# хеш строки: echo без -n добавит перевод строки и хеш будет другим
printf '%s' 'hello' | sha256sum

# сохранить суммы набора файлов
sha256sum *.txt > SHA256SUMS

# проверить: все ли файлы на месте и не изменились
sha256sum -c SHA256SUMS

# в скрипте — только код выхода
sha256sum -c --status SHA256SUMS && echo 'всё цело'

# сверить файл с опубликованным хешем (между хешем и именем — два пробела)
echo '5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03  a.txt' | sha256sum -c

# суммы всего дерева каталогов, отсортированные по имени
find data -type f -exec sha256sum {} + | sort -k2 > data.sums

# найти одинаковые файлы: одинаковый хеш = одинаковое содержимое
find . -type f -exec md5sum {} + | sort | uniq -w32 -D

Подводные камни

  • MD5 и SHA-1 не для безопасности. Для них умеют строить коллизии: два разных файла с одинаковым хешем. От случайной порчи при копировании MD5 защищает, от намеренной подмены — нет. Для проверки загрузок бери SHA-256 и сверяй хеш, полученный из надёжного источника, а не с того же сервера, что и файл.
  • Пароли хешами не хранят. sha256sum слишком быстрый — перебор займёт минуты. Для паролей существуют bcrypt, scrypt, Argon2.
  • Пути в списке относительные — как их записали. sha256sum -c надо запускать из того же каталога, иначе FAILED open or read.
  • Кривые строки игнорируются. Строку не в формате хеш имя проверка пропустит с предупреждением и всё равно может вернуть 0. Добавь --strict.
  • Перевод строки меняет хеш. echo 'hello' | sha256sum и printf 'hello' | sha256sum дают разные результаты. Так же действуют \r\n из Windows и лишний пробел в конце.
  • Регистр hex-символов при проверке не важен, а алгоритм — важен: список от md5sum в sha256sum -c даст no properly formatted checksum lines found.
  • Имена с переводом строки или обратным слешем экранируются, и строка вывода начинается с \. Это нормально, -c такие строки понимает.

См. также

openssl · find · sort · uniq · base64