crc32()
Функция crc32() вычисляет циклическую контрольную сумму строки и возвращает её в виде 32-битного целого числа.
Функция PHP crc32() вычисляет CRC-32 (Cyclic Redundancy Check) строки и возвращает результат в виде 32-битного целого числа. CRC-32 — это быстрая и лёгкая контрольная сумма: она превращает любую строку в короткий «отпечаток», по которому можно обнаружить, изменились ли данные (случайное повреждение при загрузке, ошибка диска, инвертированный бит). Это инструмент обнаружения ошибок, а не средство безопасности — см. примечания ниже.
На этой странице рассматриваются синтаксис, подводный камень со знаковыми/беззнаковыми значениями, исполняемый пример, реалистичная проверка целостности и случаи, когда лучше использовать настоящий хеш.
Синтаксис
crc32(string $string): intФункция принимает один параметр — анализируемую строку $string — и возвращает контрольную сумму CRC-32 в виде целого числа.
Подводный камень: знаковые и беззнаковые значения
CRC-32 концептуально является 32-битным беззнаковым значением (от 0 до 4 294 967 295). На 64-битных платформах PHP возвращает его как обычное положительное целое число. На 32-битных платформах значения выше 2 147 483 647 переполняются и становятся отрицательными. Чтобы везде получать одно и то же беззнаковое значение, используйте формат %u:
$unsigned = sprintf('%u', crc32($str)); // always positive, as a stringБазовый пример
Мы передаём строку в crc32() и оборачиваем результат в sprintf('%u', ...), чтобы получить согласованное значение на любой платформе. Результат выполнения кода:
3964322768Многие инструменты (а также мир cksum/zip) отображают значения CRC в шестнадцатеричном формате. Чтобы получить такой формат, используйте %08X — это даст шестнадцатеричную строку из 8 символов с ведущими нулями:
<?php
echo sprintf('%08X', crc32("Hello, World!")); // EC4AC3D0
?>Проверка целостности данных
Основное применение CRC-32 — обнаружение изменений. Вы вычисляете и сохраняете контрольную сумму один раз, затем вычисляете её снова и сравниваете — если они различаются, данные были изменены. Вот самодостаточный пример, который сохраняет контрольную сумму, а затем проверяет копию:
<?php
$data = "important payload";
// Compute and store the checksum once (e.g. in a manifest or database).
$expected_crc = crc32($data);
// Later, recompute it for the data you received and compare.
$received = "important payload";
$actual_crc = crc32($received);
if ($actual_crc === $expected_crc) {
echo "OK: data is intact.";
} else {
echo "FAIL: data has changed.";
}
?>Этот код выведет OK: data is intact.. Чтобы проверить реальный файл, замените строку на crc32(file_get_contents($filename)). Используйте строгое сравнение ===, чтобы PHP сравнивал и значение, и тип — а если ожидаемая контрольная сумма поступает в виде шестнадцатеричной строки из внешнего источника, сначала преобразуйте её с помощью (int) hexdec($expected_crc).
Важные примечания
- Не криптографически стойкая. CRC-32 легко подделать — злоумышленник может создать разные данные с одинаковой контрольной суммой. Используйте её только для обнаружения случайных ошибок, но не для паролей, подписей или защиты от подмены.
- Коллизии возможны. При всего ~4,3 миллиарда возможных значений две разные строки могут иметь одинаковую контрольную сумму. Это допустимо при обнаружении повреждений, но не при уникальной идентификации данных.
- Для безопасности или адресации контента используйте настоящий хеш. Обратитесь к
md5(),sha1()или современной функцииhash()(например, SHA-256) — а для файлов кmd5_file()/sha1_file().
Итоги
crc32() — это быстрый способ получить «отпечаток» строки для обнаружения случайных ошибок: проверки загрузок, выявления повреждённых записей или проверки данных при передаче. Не забывайте нормализовать результат с помощью sprintf('%u', ...) для единообразия на разных платформах, и используйте криптографический хеш везде, где важна безопасность.