The following function sometimes returns 5 digits instead of 6:
https://github.com/dgryski/dgoogauth/blob/96977cbd42e27be71f9f731db6634123de7e861a/googauth.go#L27-L49
e.g.
package main
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base32"
"encoding/binary"
"fmt"
"time"
"github.com/dgryski/dgoogauth"
)
func main() {
secret := []byte{'H', 'e', 'l', 'l', 'o', '!', 0xDE, 0xAD, 0xBE, 0xEF}
secretEnc := base32.StdEncoding.EncodeToString(secret)
var t0 int64
t0 = int64(time.Now().Unix() / 2)
code := dgoogauth.ComputeCode(secretEnc, t0)
fmt.Printf("code = %+v\n", code)
}
func ComputeCode(secret string, value int64) int {
key, err := base32.StdEncoding.DecodeString(secret)
if err != nil {
return -1
}
hash := hmac.New(sha1.New, key)
err = binary.Write(hash, binary.BigEndian, value)
if err != nil {
return -1
}
h := hash.Sum(nil)
offset := h[19] & 0x0f
truncated := binary.BigEndian.Uint32(h[offset : offset+4])
truncated &= 0x7fffffff
code := truncated % 1000000
return int(code)
}
Outputs the following when looped:
code = 292234
code = 108363
code = 108363
code = 828914
code = 45510
code = 45510
code = 45288
code = 45288
code = 286406
code = 166336
code = 166336
code = 569768
code = 569768