Зачем сверять хеш и что он подтверждает
Контрольная сумма, или хеш, — короткая строка, которую программа вычисляет по содержимому файла. Если изменится хотя бы один байт, результат, как правило, будет совсем другим. Поэтому хеш используют, чтобы проверить, что файл скачался или скопировался без повреждений: вы считаете сумму у себя и сравниваете с той, которую указал автор.
Важно понимать границы. Совпадение подтверждает, что ваш файл идентичен тому, для которого сумма была вычислена. Но если и файл, и сумма лежат в одном месте и их заменил кто-то посторонний, сравнение это не выявит. Чтобы проверка имела смысл против подмены, эталонное значение должно приходить из другого, независимого канала, например с официальной страницы проекта, открытой по проверенному адресу.
Какие алгоритмы встречаются в обиходе:
- MD5 даёт 32 шестнадцатеричных символа и сегодня считается устаревшим для защиты от намеренной подмены; для обнаружения случайных ошибок копирования он годится;
- SHA-1 даёт 40 символов и тоже не рекомендуется для задач безопасности;
- SHA-256 даёт 64 символа и широко применяется в современных публикациях сумм.
Подробнее о свойствах хеш-функций написано в разделе словаря, а разницу MD5 и SHA-256 разбирает сравнительная статья, обе есть среди связанных.
Linux: sha256sum и md5sum
В большинстве дистрибутивов Linux утилиты из набора coreutils уже установлены. Выполните sha256sum имя_файла: программа напечатает хеш, затем два пробела (или пробел и звёздочку) и имя файла. Для MD5 команда называется md5sum и работает так же. Для другой длины SHA есть команды sha1sum, sha512sum и им подобные.
Чтобы сверить результат с эталоном, не обязательно сравнивать длинные строки глазами. Есть два удобных пути. Первый: сохранить эталон в файл формата «хеш, два пробела, имя» и запустить проверку ключом -c, например sha256sum -c файл_с_суммами. Утилита прочитает список и для каждого файла напечатает имя и слово OK, либо слово FAILED, если сумма не совпала. Если файл из списка отсутствует, будет сообщение об ошибке чтения.
Второй путь — подать эталонную строку прямо в конвейер: echo 'хеш имя_файла' | sha256sum -c -. Между хешем и именем должно стоять два пробела, этот формат утилита ожидает.
Ключ -c удобен и тем, что его вывод пригоден для скриптов: код возврата ненулевой, если хотя бы одна проверка завершилась неудачей. Дополнительные ключи вроде пропуска отсутствующих файлов зависят от версии, поэтому смотрите sha256sum --help.
macOS: shasum и md5
В macOS утилит sha256sum и md5sum по умолчанию нет, но есть аналоги. Для SHA используется shasum: команда shasum -a 256 имя_файла выводит хеш SHA-256 в том же формате, что и Linux. Ключ -a задаёт алгоритм. Без него shasum считает SHA-1, и это легко упустить, получив сумму не той длины.
Для MD5 в macOS есть команда md5, но формат её вывода отличается: она печатает строку вида MD5 (имя_файла) = хеш. Такой вывод нельзя напрямую подать на проверку ключом -c, зато сравнить значение глазами или командой можно.
| Задача | Linux | macOS |
|---|---|---|
| SHA-256 одного файла | sha256sum файл | shasum -a 256 файл |
| MD5 одного файла | md5sum файл | md5 файл |
| Проверка списком | sha256sum -c список | shasum -a 256 -c список |
| Несколько файлов | sha256sum файл1 файл2 | shasum -a 256 файл1 файл2 |
Ключ -c в shasum принимает тот же формат списка, что и в Linux, поэтому файл с суммами, созданный на одной системе, можно проверить на другой. Если при проверке команда сообщает о неверном формате строк, посмотрите, не вставились ли вместе с суммой лишние символы или переводы строк другого вида.
Если хеш не совпал
Несовпадение не означает, что файл «взломан». Чаще причины обыденны. Просмотрите их по порядку, прежде чем делать выводы.
- Сравниваются разные алгоритмы. Проверьте длину строки: 64 символа соответствуют SHA-256, 32 символа MD5, 40 символов SHA-1.
- Файл скачан не полностью или прерван. Размер в ls -l меньше, чем указано на странице загрузки.
- Сравнивается не тот файл: например, архив и распакованное содержимое, или другая версия.
- В эталонную строку попали лишние пробелы или переносы строк (в том числе в стиле Windows). Регистр букв в шестнадцатеричной записи значения не меняет, но формат строки для ключа -c утилита разбирает строго.
- Файл действительно был изменён при передаче.
Тогда скачайте файл заново, желательно из другого источника, проверьте ещё раз и, если расхождение повторяется, не запускайте этот файл. Запускать неподтверждённые программы небезопасно даже при хорошем намерении.
Для работы в Windows есть своя команда certutil -hashfile или командлет Get-FileHash в PowerShell, но это уже другой раздел. Для сравнения двух файлов между собой хеш тоже подходит: одинаковые суммы говорят об одинаковом содержимом, и для больших файлов это удобнее, чем сравнивать их построчно через diff.
Хеш папки и другие нюансы
Утилиты вычисляют сумму для одного файла, а не для каталога. Если нужно сверить целую папку, обычно строят список сумм всех файлов в ней: выводят find с условием -type f и передают имена в sha256sum через xargs, после чего сохраняют результат в файл. Затем на другой стороне этот файл проверяют ключом -c. Порядок вывода find может меняться, поэтому для сравнения двух списков сначала отсортируйте их.
Пример схемы для Linux (условная запись, выполняйте на тестовой папке): find папка -type f -print0 | xargs -0 sha256sum > sums.txt. Такая запись корректно справляется с пробелами в именах благодаря паре -print0 и -0, подробности есть в статье про find.
Ещё несколько замечаний:
- хеш не зависит от имени, времени и прав файла, только от содержимого;
- хеш нельзя «расшифровать» обратно в файл, это односторонняя операция;
- для больших файлов вычисление занимает заметное время, и это нормально: программа читает файл целиком.
Если важна не только целостность, но и подлинность, разработчики публикуют цифровые подписи, а не только суммы. Как проверять подписи, зависит от проекта, и общего рецепта тут нет.