Crc32: примеры (PHP)
crc32(string $string): intФункция crc32 вычисляет полиномиальную контрольную сумму для строки, используя 32-битный алгоритм Cyclic Redundancy Check (CRC). Этот алгоритм часто применяется для проверки целостности данных, но не для криптографических целей, так как не является устойчивым к коллизиям.
Основное применение - быстрая проверка изменений в данных, создание коротких хешей для сравнения или использование в сетевых протоколах.
Сигнатура функции:crc32(string $string): int
Функция принимает один обязательный параметр:
- $string (string) - строка, для которой вычисляется контрольная сумма CRC32.
Возвращаемое значение - целое число (int) со знаком, представляющее контрольную сумму CRC32. На 32-битных системах результат может быть отрицательным числом.
Код:
$str = "Hello, world!";
$crc = crc32($str);
echo "CRC32: " . $crc;
// Для получения шестнадцатеричного представления
printf("CRC32 (hex): %x", $crc);Результат:
CRC32: -1372190028 CRC32 (hex): ae1992b4
Код:
$data1 = "Test string";
$data2 = "Test string";
$data3 = "Test string "; // с пробелом в конце
$crc1 = crc32($data1);
$crc2 = crc32($data2);
$crc3 = crc32($data3);
var_dump($crc1 === $crc2); // идентичные строки
var_dump($crc1 === $crc3); // разные строкиРезультат:
bool(true) bool(false)
PHP предлагает несколько функций для хеширования и создания контрольных сумм:
- md5() - вычисляет MD5-хеш строки. Возвращает 32-символьный шестнадцатеричный номер. Быстрее, чем crypt(), но также не рекомендуется для безопасности.
- sha1() - вычисляет SHA1-хеш строки. Возвращает 40-символьный шестнадцатеричный номер. Надежнее MD5, но также имеет уязвимости.
- hash() - универсальная функция для вычисления хешей с использованием различных алгоритмов (crc32, md5, sha256 и др.). Для CRC32:
hash('crc32', $string)возвращает 8-символьное шестнадцатеричное значение без знака.
Когда использовать crc32: для быстрой проверки целостности данных, в внутренних процессах, где важна скорость, а не криптографическая стойкость.
Когда использовать hash() с другими алгоритмами: для проверки паролей, цифровых подписей, обеспечения безопасности.
Crc32 в Python
Модуль zlib или binascii:
import zlib
str_data = b"Hello, world!"
crc_value = zlib.crc32(str_data)
print(f"CRC32: {crc_value}")
print(f"CRC32 (hex): {crc_value & 0xFFFFFFFF:08x}")CRC32: 2923460726 CRC32 (hex): ae1992b4
Crc32 в Javascript
Нет встроенной функции, но можно использовать сторонние библиотеки или реализовать самостоятельно:
// Пример с использованием библиотеки crc-32
// npm install crc-32
// const CRC32 = require('crc-32');
// let crc = CRC32.str("Hello, world!");
// console.log(crc); // -1372190028Crc32 в MySQL
Функция CRC32():
SELECT CRC32('Hello, world!');
-- Результат: 2923460726 (беззнаковый)2923460726
Основное отличие PHP crc32 от других реализаций - возврат знакового целого на 32-битных системах, в то время как другие языки часто возвращают беззнаковое значение.
При сравнении результатов crc32 на разных системах (32-битных и 64-битных) могут возникнуть проблемы из-за разного представления отрицательных чисел.
// На 32-битной системе
$crc = crc32("test");
// Может вернуть отрицательное число, например -662733300
// На 64-битной системе та же строка вернет 3632233996
// Прямое сравнение не сработаетРешение: использовать sprintf() для получения шестнадцатеричного представления или преобразование в беззнаковое число:
$crc = crc32("test");
$crc_unsigned = sprintf("%u", $crc);
echo $crc_unsigned; // Всегда беззнаковое представлениеCRC32 не предназначен для безопасности:
// НЕПРАВИЛЬНО: использование crc32 для хеширования паролей
$password_hash = crc32($password);
// Легко подобрать коллизииФункция crc32 не претерпела значительных изменений в последних версиях PHP. Поведение функции остается стабильным на протяжении многих релизов.
Начиная с PHP 7, все целочисленные значения имеют разрядность 64-бит на всех поддерживаемых платформах, что упрощает работу с результатами crc32 и уменьшает проблемы с переносимостью между 32-битными и 64-битными системами.
В PHP 8 не было внесено изменений в работу функции crc32, что свидетельствует о ее зрелости и стабильности.
CRC32 может использоваться для быстрой проверки неизменности данных:
function createDataPacket($data) {
$crc = crc32($data);
return $data . pack('V', $crc); // Добавляем CRC32 в конец данных
}
function verifyDataPacket($packet) {
if (strlen($packet) < 4) return false;
$data = substr($packet, 0, -4);
$received_crc = unpack('V', substr($packet, -4))[1];
$calculated_crc = crc32($data);
// Приведение к беззнаковому виду для сравнения
$received_crc_unsigned = sprintf("%u", $received_crc);
$calculated_crc_unsigned = sprintf("%u", $calculated_crc);
return $received_crc_unsigned === $calculated_crc_unsigned;
}
$original = "Important data";
$packet = createDataPacket($original);
echo "Пакет с CRC: " . bin2hex($packet) . "\n";
echo "Проверка оригинала: " . (verifyDataPacket($packet) ? "OK" : "FAIL") . "\n";
// Изменяем пакет
$tampered = substr($packet, 0, -5) . "X" . substr($packet, -4);
echo "Проверка измененного: " . (verifyDataPacket($tampered) ? "OK" : "FAIL") . "\n";Пакет с CRC: 496d706f7274616e742064617461b49219ae Проверка оригинала: OK Проверка измененного: FAIL
function getFileCRC($filename, $chunkSize = 8192) {
if (!file_exists($filename)) return false;
$crc = 0;
$fp = fopen($filename, 'rb');
while (!feof($fp)) {
$data = fread($fp, $chunkSize);
$crc = crc32($data, $crc);
}
fclose($fp);
return $crc;
}
// Сравнение двух файлов по CRC32
$file1 = 'file1.txt';
$file2 = 'file2.txt';
$crc1 = getFileCRC($file1);
$crc2 = getFileCRC($file2);
if ($crc1 !== false && $crc2 !== false) {
echo "Файл 1 CRC: " . sprintf("%u", $crc1) . "\n";
echo "Файл 2 CRC: " . sprintf("%u", $crc2) . "\n";
echo "Файлы " . ($crc1 === $crc2 ? "идентичны" : "различаются") . "\n";
}function shortHash($data, $length = 8) {
$crc = crc32($data);
// Преобразуем в беззнаковое число и затем в шестнадцатеричное
$hex = dechex(sprintf("%u", $crc));
// Возвращаем указанное количество символов
return substr($hex, 0, $length);
}
$id1 = shortHash("user@example.com");
$id2 = shortHash("user@example.com", 4);
$id3 = shortHash("another@domain.com");
echo "ID1 (8 chars): $id1\n";
echo "ID2 (4 chars): $id2\n";
echo "ID3 (8 chars): $id3\n";ID1 (8 chars): 8e657d77 ID2 (4 chars): 8e65 ID3 (8 chars): 9a3e8a9f
CRC32 часто используется в форматах архивов и протоколах передачи данных:
// Упрощенная эмуляция проверки данных по примеру ZIP
function simulateZipCheck($compressedData, $originalCrc) {
// В реальности здесь была бы декомпрессия
$calculatedCrc = crc32($compressedData);
$originalUnsigned = sprintf("%u", $originalCrc);
$calculatedUnsigned = sprintf("%u", $calculatedCrc);
return $originalUnsigned === $calculatedUnsigned;
}
$data = "Compressed data here";
$storedCrc = crc32($data); // Эмуляция CRC, записанного в архив
// Проверка целостности
$isValid = simulateZipCheck($data, $storedCrc);
echo "Данные архива: " . ($isValid ? "не повреждены" : "повреждены") . "\n";