<?php
function totpCode(string $base32Secret, ?int $time = null): string {
$secret = base32Decode($base32Secret);
$counter = pack('J', intdiv($time ?? time(), 30));
$hash = hash_hmac('sha1', $counter, $secret, true);
$off = ord($hash[19]) & 0x0F;
$bin = (ord($hash[$off]) & 0x7F) << 24 | (ord($hash[$off+1]) & 0xFF) << 16
| (ord($hash[$off+2]) & 0xFF) << 8 | ord($hash[$off+3]) & 0xFF;
return str_pad((string)($bin % 1_000_000), 6, '0', STR_PAD_LEFT);
}
function base32Decode(string $s): string {
$alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
$s = strtoupper(rtrim($s, '='));
$bin = '';
foreach (str_split($s) as $c) {
$i = strpos($alpha, $c);
if ($i !== false) $bin .= str_pad(decbin($i), 5, '0', STR_PAD_LEFT);
}
$out = '';
foreach (str_split($bin, 8) as $byte) {
if (strlen($byte) === 8) $out .= chr(bindec($byte));
}
return $out;
}
echo totpCode('JBSWY3DPEHPK3PXP'); // 6-digit code, valid for ~30s
Create a free account and build your private vault. Share publicly whenever you want.