+# hotp/totp code
+
+sub hotp($$;$) {
+ my ($binsecret, $number, $digits) = @_;
+
+ $digits = 6 if !defined($digits);
+
+ my $bincounter = pack('Q>', $number);
+ my $hmac = Digest::SHA::hmac_sha1($bincounter, $binsecret);
+
+ my $offset = unpack('C', substr($hmac,19) & pack('C', 0x0F));
+ my $part = substr($hmac, $offset, 4);
+ my $otp = unpack('N', $part);
+ my $value = ($otp & 0x7fffffff) % (10**$digits);
+ return sprintf("%0${digits}d", $value);
+}
+