Skip to content

Instantly share code, notes, and snippets.

@AminCoder
Last active January 27, 2025 06:45
Show Gist options
  • Save AminCoder/5d970ab8a0e04d9dd3218e5627ae6b13 to your computer and use it in GitHub Desktop.
Save AminCoder/5d970ab8a0e04d9dd3218e5627ae6b13 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base32"
"encoding/binary"
"fmt"
"math"
"time"
)
func generate_topt(secret string, interval int64, digits int) (string, error) {
key, err := base32.StdEncoding.DecodeString(secret)
if err != nil {
return "", fmt.Errorf("failed to decode secret: %w", err)
}
time_step := time.Now().Unix() / interval
var counter_bytes [8]byte
binary.BigEndian.PutUint64(counter_bytes[:], uint64(time_step))
hmac_hash := hmac.New(sha1.New, key)
if _, err := hmac_hash.Write(counter_bytes[:]); err != nil {
return "", fmt.Errorf("failed to write HMAC: %w", err)
}
hash := hmac_hash.Sum(nil)
offset := hash[len(hash)-1] & 0x0F
code := (int(hash[offset])&0x7F)<<24 |
(int(hash[offset+1])&0xFF)<<16 |
(int(hash[offset+2])&0xFF)<<8 |
(int(hash[offset+3]) & 0xFF)
otp := code % int(math.Pow10(digits))
return fmt.Sprintf("%0*d", digits, otp), nil
}
func main() {
// secret key
secret := "JBSWY3DPEHPK3PXP"
// Generate a 6-digit TOTP with 30-second intervals
totp, err := generate_topt(secret, 30, 6)
if err != nil {
fmt.Println("Error generating TOTP:", err)
return
}
fmt.Println("Your TOTP code is:", totp)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment