base32Decode($secret)); $offset = ord($hash[19]) & 0x0F; $otp = ((ord($hash[$offset]) & 0x7F) << 24 | (ord($hash[$offset+1]) & 0xFF) << 16 | (ord($hash[$offset+2]) & 0xFF) << 8 | (ord($hash[$offset+3]) & 0xFF)) % 1000000; if (str_pad((string)$otp, 6, '0', STR_PAD_LEFT) === $code) return true; } return false; } private function base32Decode(string $base32): string { $base32chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; $base32charsFlipped = array_flip(str_split($base32chars)); $output = ''; $v = 0; $vbits = 0; for ($i = 0, $j = strlen($base32); $i < $j; $i++) { $v <<= 5; if (isset($base32charsFlipped[$base32[$i]])) { $v += $base32charsFlipped[$base32[$i]]; } $vbits += 5; while ($vbits >= 8) { $vbits -= 8; $output .= chr(($v >> $vbits) & 0xFF); } } return $output; } }