module simpletotp.hotp; import std.string; import std.digest.sha; import std.digest.hmac; enum TOK_LEN = 6; enum T0 = 0; enum TI = 30; int hotp(const ubyte[] K, ulong C, const int digits = TOK_LEN) { ubyte[8] counter; for (int i = 8; i --> 0;) { counter[i] = C & 0xFF; C >>= 8; } auto hmac = HMAC!SHA1(K); hmac.put(counter); ubyte[20] hash = hmac.finish(); int offset = hash[19] & 0x0F; uint value = 0; for (int i = 0; i < 4; ++i) { value <<= 8; value |= hash[offset + i]; } value &= 0x7F_FF_FF_FF; static const int[10] pow10 = [ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 ]; return value % pow10[digits]; } int hotp(const string K, ulong C, const int digits = TOK_LEN) { return hotp(K.representation, C, digits); }