Я пытаюсь написать код проверки на PhP, выполнив следующие действия...
Код подтверждения рассчитывается по:
Пока у меня есть этот код, но он работает не так, как я надеялся:
function calculateVcode($hashString) {
$md = hash_init('sha256');
$hash = base64_decode($hashString);
hash_update($md, $hash);
$hash = hash_final($md, true);
$last = substr($hash, -2);
$code = bindec($last);
return substr(strval($code), -4);
}
$hashString = "Demo string for Authentication";
$md5Hash = md5($hashString);
$result = calculateVcode($md5Hash);`
Есть идеи, как заставить это работать, или я совершенно на неправильном пути?
Результат может быть таким: Текст, используемый для создания хэш-строки «Аутентификация приложения Auðkenni»
Сгенерирована хэш-строка n/kRNhXaZ2jFKv8KlQX7ydgedXUmVy8b2O4xNq2ZxHteG7wOvCa0Kg3rY1JLOrOBXYQm+z2FRVwIv47w8gUb5g==
Проверочный код, рассчитанный на основе хэша 4141






Для правильного хеширования SHA-256 вам нужны необработанные двоичные данные, которые представляет MD5, а не их закодированная или строковая версия. Если вы начинаете с хеш-строки MD5, вам следует преобразовать эту строку обратно в двоичный формат, если она закодирована в шестнадцатеричном формате, или убедиться, что вы имеете дело непосредственно с двоичными данными.
Кроме того, способ преобразования последних двух байтов в целое число не совсем верен. Функция bindec() не предназначена для преобразования двоичных данных непосредственно в целые числа, поскольку она интерпретирует двоичную строку, а не необработанные байты.
Как только они будут исправлены, вы должны ожидать ожидаемых результатов:
function calculateVcode($hashString) {
// Assume $hashString is already a proper byte sequence
$hash = hash('sha256', $hashString, true); // true for raw binary output
$lastTwoBytes = substr($hash, -2); // Get the last 2 bytes
$value = unpack("n", $lastTwoBytes); // Unpack as a big-endian ushort (16-bit int)
$code = $value[1] % 10000; // get last 4 digits
return $code;
}
$originalText = "Auðkenni APP Authentication";
$hashString = base64_decode("n/kRNhXaZ2jFKv8KlQX7ydgedXUmVy8b2O4xNq2ZxHteG7wOvCa0Kg3rY1JLOrOBXYQm+z2FRVwIv47w8gUb5g= = ");
$result = calculateVcode($hashString);
echo "Verification code: " . $result . "\n";
Кстати: ваш метод получения последних 4 цифр может привести к ошибкам, если преобразованное целое число имеет длину менее 4 цифр.
как лучше всего создать необработанную хэш-строку?
Я бы сгенерировал необработанный (в двоичной форме) хэш SHA-512 ваших данных. Затем закодируйте его в Base64, что необходимо для передачи или сохранения хеша в текстовом формате. Когда вам понадобится использовать этот хэш для дальнейшей обработки (например, для расчета проверочного кода), вы декодируете его из Base64 обратно в исходную необработанную двоичную форму:
function createBase64EncodedSHA512(string $input): string {
$rawHash = hash('sha512', $input, true);
return base64_encode($rawHash);
}
function calculateVcodeFromBase64SHA512(string $base64EncodedHash): int {
$hashBytes = base64_decode($base64EncodedHash);
$hash = hash('sha256', $hashBytes, true);
$lastTwoBytes = substr($hash, -2);
$value = unpack("n", $lastTwoBytes);
$code = $value[1] % 10000;
return $code;
}
Пример использования
$inputData = "Your data here";
$base64SHA512 = createBase64EncodedSHA512($inputData);
$verificationCode = calculateVcodeFromBase64SHA512($base64SHA512);
echo "Verification Code: " . $verificationCode . "\n";
Спасибо, Марцин, отличный вклад, и я вижу свои ошибки. Но что касается ввода в функцию, как лучше всего создать необработанную хэш-строку? В инструкциях говорится: вам нужно будет предоставить хеш-строку для использования. Таким образом вы можете рассчитать код подтверждения на своей стороне, чтобы отобразить его на вашем веб-сайте, чтобы его мог увидеть ваш пользователь. Хэш-строка должна иметь тип SHA512. Обратите внимание, что хеш-строка должна быть в формате Base64.
Спасибо, Марчин! Абсолютно великолепно, вы решили для меня эту загадку.
Почему вы используете
base64_decode()для результатаmd5()?