password_hash($c, PASSWORD_BCRYPT), $codes)); } public static function verifyBackupCode(string $code, string $hashedJson): bool { $hashes = json_decode($hashedJson, true) ?? []; foreach ($hashes as $hash) { if (password_verify(strtoupper($code), $hash)) return true; } return false; } private static function base32Decode(string $base32): string { $base32 = strtoupper(preg_replace('/[^A-Z2-7]/', '', $base32)); $buf = 0; $bits = 0; $out = ''; for ($i = 0; $i < strlen($base32); $i++) { $val = strpos(self::CHARS, $base32[$i]); $buf = ($buf << 5) | $val; $bits += 5; if ($bits >= 8) { $bits -= 8; $out .= chr(($buf >> $bits) & 0xFF); } } return $out; } }