<?php

if (!function_exists('pbkdf2_hash')) {
    function pbkdf2_hash(string $password, string $algo = 'sha256', int $iterations = 100000, int $length = 64): string
    {
        $salt = random_bytes(16); // 16 bytes = 32 hex characters
        $salt_hex = bin2hex($salt);

        $derived_key = hash_pbkdf2($algo, $password, $salt, $iterations, $length, true);
        $derived_key_hex = bin2hex($derived_key);

        return "{$algo}\${$iterations}\${$salt_hex}\${$derived_key_hex}";
    }
}

if (!function_exists('pbkdf2_verify')) {
    function pbkdf2_verify(string $password, string $stored_hash): bool
    {
        $parts = explode('$', $stored_hash);

        if (count($parts) !== 4) {
            return false; // Invalid format
        }

        [$algo, $iterations, $salt_hex, $derived_key_hex] = $parts;

        if (strlen($salt_hex) % 2 !== 0 || strlen($derived_key_hex) % 2 !== 0) {
            return false; // Not valid hex
        }

        $salt = hex2bin($salt_hex);
        $derived_key = hex2bin($derived_key_hex);
        $length = strlen($derived_key);

        $new_derived_key = hash_pbkdf2($algo, $password, $salt, (int)$iterations, $length, true);

        return hash_equals($derived_key, $new_derived_key);
    }
}
