Skip to content

Instantly share code, notes, and snippets.

@tilaklodha
Last active June 1, 2018 10:12
Show Gist options
  • Save tilaklodha/99566da21edf6f4f0616d914380f27fa to your computer and use it in GitHub Desktop.
Save tilaklodha/99566da21edf6f4f0616d914380f27fa to your computer and use it in GitHub Desktop.
func getHOTPToken(secret string, interval int64) string {
//Converts secret to base32 Encoding. Base32 encoding desires a 32-character
//subset of the twenty-six letters A–Z and ten digits 0–9
key, err := base32.StdEncoding.DecodeString(strings.ToUpper(secret))
check(err)
bs := make([]byte, 8)
binary.BigEndian.PutUint64(bs, uint64(interval))
//Signing the value using HMAC-SHA1 Algorithm
hash := hmac.New(sha1.New, key)
hash.Write(bs)
h := hash.Sum(nil)
// We're going to use a subset of the generated hash.
// Using the last nibble (half-byte) to choose the index to start from.
// This number is always appropriate as it's maximum decimal 15, the hash will
// have the maximum index 19 (20 bytes of SHA1) and we need 4 bytes.
o := (h[19] & 15)
var header uint32
//Get 32 bit chunk from hash starting at the o
r := bytes.NewReader(h[o : o+4])
err = binary.Read(r, binary.BigEndian, &header)
check(err)
//Ignore most significant bits as per RFC 4226.
//Takes division from one million to generate a remainder less than < 7 digits
h12 := (int(header) & 0x7fffffff) % 1000000
//Converts number as a string
otp := strconv.Itoa(int(h12))
return prefix0(otp)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment