Sha1 file: примеры (PHP)
sha1_file(string filename [, bool binary]): string|falseФункция sha1_file в PHP
Функция sha1_file() вычисляет SHA1-хеш файла. Она используется для получения уникального хеш-идентификатора содержимого файла. Этот идентификатор можно применять для проверки целостности данных, сравнения файлов или создания контрольных сумм.
Функция принимает до двух параметров.
filename (обязательный): Путь к файлу, для которого вычисляется хеш. Если указан URL, функция попытается открыть поток через обертку URL.
binary (опциональный, по умолчанию false): Логический параметр. Если установлен в true, функция возвращает необработанный бинарный результат длиной 20 символов. Если false (по умолчанию), возвращается шестнадцатеричная строка длиной 40 символов.
Простые примеры использования
<?
$hash = sha1_file('document.pdf');
echo $hash;
?>da39a3ee5e6b4b0d3255bfef95601890afd80709
<?
$binary_hash = sha1_file('image.jpg', true);
echo 'Длина бинарного хеша: ' . strlen($binary_hash);
?>Длина бинарного хеша: 20
<?
$expected_hash = '5ba93c9db0cff93f52b521d7420e43f6eda2784f';
$actual_hash = sha1_file('archive.zip');
if ($actual_hash === $expected_hash) {
echo 'Файл не изменен.';
} else {
echo 'Файл поврежден или изменен.';
}
?>Файл не изменен.
Альтернативные функции в PHP
PHP предлагает несколько функций для хеширования файлов, каждая со своими особенностями.
Вычисляет MD5-хеш файла. Алгоритм MD5 считается криптографически нестойким для целей безопасности, но может быть полезен для быстрой проверки целостности в неопасных сценариях. Возвращает 32-символьную шестнадцатеричную строку.
Более универсальная функция. Позволяет вычислять хеш, используя множество алгоритмов (например, sha256, sha512, ripemd160). Функцию sha1_file() можно считать частным случаем hash_file('sha1', $filename). Для новых проектов, особенно требующих безопасности, предпочтительнее использовать hash_file() с более стойким алгоритмом, таким как sha256.
Функция работает со строками, но в комбинации с file_get_contents() может использоваться для файлов. CRC32 создает 32-битную контрольную сумму, которая не является криптографическим хешем. Она применяется для быстрого обнаружения случайных изменений данных (например, в сетевых пакетах или архивах).
Аналоги в других языках
Sha1 file в Python
Используется модуль hashlib. Отличие: требует явного открытия и чтения файла блоками для больших файлов.
import hashlib
def sha1_of_file(filename):
sha1 = hashlib.sha1()
with open(filename, 'rb') as f:
while chunk := f.read(8192):
sha1.update(chunk)
return sha1.hexdigest()
print(sha1_of_file('test.txt'))da39a3ee5e6b4b0d3255bfef95601890afd80709
Используется модуль crypto. Функция создает хеш из содержимого файла асинхронно.
const crypto = require('crypto');
const fs = require('fs');
function sha1File(filePath) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha1');
const stream = fs.createReadStream(filePath);
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => resolve(hash.digest('hex')));
stream.on('error', reject);
});
}
sha1File('test.txt').then(console.log);da39a3ee5e6b4b0d3255bfef95601890afd80709
Sha1 file в MySQL
Функция SHA1() работает только со строками. Для файлов необходимо сначала загрузить содержимое в базу данных.
SELECT SHA1(LOAD_FILE('/tmp/test.txt')) AS file_hash;+------------------------------------------+ | file_hash | +------------------------------------------+ | da39a3ee5e6b4b0d3255bfef95601890afd80709 | +------------------------------------------+
Типичные ошибки
Функция возвращает false и генерирует предупреждение уровня E_WARNING.
<?
$result = sha1_file('/несуществующий/файл.txt');
var_dump($result);
?>Warning: sha1_file(/несуществующий/файл.txt): Failed to open stream: No such file or directory in ... bool(false)
Передача аргумента неверного типа приводит к ошибке TypeError в строгом режиме.
<?
declare(strict_types=1);
try {
sha1_file(null);
} catch (TypeError $e) {
echo 'Ошибка: ' . $e->getMessage();
}
?>Ошибка: sha1_file(): Argument #1 ($filename) must be of type string, null given
Хеш пустого файла всегда одинаков, что иногда не ожидается.
<?
file_put_contents('empty.txt', '');
echo sha1_file('empty.txt');
?>da39a3ee5e6b4b0d3255bfef95601890afd80709
Изменения в последних версиях PHP
В PHP 8.0 сигнатура функции была приведена к строгой типизации. Аргумент $filename теперь имеет тип string, а $binary - bool. Передача значений других типов вызывает TypeError. До PHP 8.0 такие аргументы неявно преобразовывались в нужный тип.
В PHP 7.1 была добавлена возможность указывать $binary как строгий boolean. Ранее небулевые значения могли преобразовываться.
Расширенные примеры применения
<?
function getDirHash($dirPath) {
$hashes = [];
$files = scandir($dirPath);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$fullPath = $dirPath . DIRECTORY_SEPARATOR . $file;
if (is_file($fullPath)) {
$hashes[$file] = sha1_file($fullPath);
}
}
ksort($hashes);
return sha1(implode('', $hashes)); // Хеш от конкатенации всех хешей файлов
}
$hash1 = getDirHash('dir1');
$hash2 = getDirHash('dir2');
echo 'Каталоги идентичны по содержимому файлов: ' . ($hash1 === $hash2 ? 'Да' : 'Нет');
?>Каталоги идентичны по содержимому файлов: Нет
<?
$cssFile = 'styles.css';
$versionToken = substr(sha1_file($cssFile), 0, 8); // Берем первые 8 символов
?>
<?
$dir = 'uploads';
$fileHashMap = [];
$duplicates = [];
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($iterator as $file) {
if ($file->isFile()) {
$filePath = $file->getPathname();
$hash = sha1_file($filePath);
if (isset($fileHashMap[$hash])) {
$duplicates[$hash][] = $filePath;
} else {
$fileHashMap[$hash] = $filePath;
}
}
}
foreach ($duplicates as $hash => $paths) {
echo "Дубликаты (хеш $hash):
";
foreach ($paths as $path) {
echo " - $path
";
}
}
?>Дубликаты (хеш a94a8fe5ccb19ba61c4c0873d391e987982fbbd3):
- uploads/image_copy.jpg
- uploads/image.jpg
<?
$allowedHashes = [
'5ba93c9db0cff93f52b521d7420e43f6eda2784f',
'd6f107c3c9b7e3b3e8e5e8e3c3b9b7e3b3e8e5e8'
];
$uploadedFile = $_FILES['document']['tmp_name'];
$uploadedHash = sha1_file($uploadedFile);
if (in_array($uploadedHash, $allowedHashes, true)) {
echo 'Файл разрешен для загрузки.';
} else {
echo 'Загрузка файла запрещена.';
}
?>Файл разрешен для загрузки.