public static int GetCode(
HashAlgorithm algorithm,
string secret,
DateTime datetime,
int digits = Otp.DefaultDigits,
int period = Totp.DefaultPeriod)
{
Contract.Requires<ArgumentOutOfRangeException>(Enum.IsDefined(typeof(HashAlgorithm), algorithm));
Contract.Requires<ArgumentOutOfRangeException>(algorithm != HashAlgorithm.Unknown);
Contract.Requires<ArgumentNullException>(secret != null);
Contract.Requires<ArgumentNullException>(datetime != null);
Contract.Requires<ArgumentException>(Enum.IsDefined(typeof(DateTimeKind), datetime.Kind));
Contract.Requires<ArgumentException>(datetime.Kind != DateTimeKind.Unspecified);
Contract.Requires<ArgumentOutOfRangeException>(digits > 0);
Contract.Requires<ArgumentOutOfRangeException>(period > 0);
Contract.Ensures(Contract.Result<int>() > 0);
Contract.Ensures(Contract.Result<int>() < Math.Pow(10, digits));
datetime = datetime.Kind == DateTimeKind.Utc ? datetime : datetime.ToUniversalTime();
var unixTime = datetime.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
var counter = (long) (unixTime * 1000) / (period * 1000);
return Otp.GetCode(algorithm, secret, counter, digits);
}