Google has a lot of answers for you. But first of all you have to decide the hash you want to use, the password length, compexity, if you need to comply with a standard, and so on. But this is a good start:
public static int CalculateHotp(byte[] key, byte[] counter)
{
var hmacsha1 = new HMACSHA1(key);
byte[] hmac_result = hmacsha1.ComputeHash(counter);
int offset = hmac_result[19] & 0x0f;
int bin_code = (hmac_result[offset] & 0x7f) << 24
| (hmac_result[offset+1] & 0xff) << 16
| (hmac_result[offset+2] & 0xff) << 8
| (hmac_result[offset+3] & 0xff);
int hotp = bin_code % 1000000;
return hotp;
}
(
copied from here[
^])
Update:
using System;
using System.Security.Cryptography;
using System.Text;
namespace OTATest
{
static class OTAGenerator
{
private static char[] pwdCharArray = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()-_=+[]{}\\|;:'\",<.>/?".ToCharArray();
public static string GenerateOTA(int keyLength = 10)
{
using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
{
StringBuilder sBuilder = new StringBuilder();
byte[] key = new byte[1];
for (int i = 0; i < keyLength; i++)
{
do
{
rngCsp.GetNonZeroBytes(key);
}
while (key[0] > pwdCharArray.Length);
sBuilder.Append(pwdCharArray[key[0]]);
}
return sBuilder.ToString();
}
}
}
}