induwara.lk
induwara.lkUtility · Security

TOTP / 2FA Authenticator Code Generator

Turn a Base32 secret into the live 6- or 8-digit authenticator code your 2FA app would show right now — with a countdown to the next code — or generate a fresh secret plus a scannable QR to set up two-factor authentication. RFC 6238, runs entirely in your browser.

By Induwara AshinsanaUpdated Jul 15, 2026
TOTP / 2FA code generator

For testing and learning only. Use a throwaway or test secret — never paste a live production account's 2FA secret into any website, including this one. Everything here runs in your browser; your secret is never sent anywhere.

Letters A–Z and digits 2–7. Spaces, hyphens and lower-case are accepted; padding is ignored.

Time source

Computing…

Follows RFC 6238 (TOTP), RFC 4226 (HOTP) and RFC 4648 (Base32). Algorithm last cross-checked against the RFC 6238 test vectors on 2026-07-15. Full sources are listed below the tool.

How it works

A time-based one-time password (TOTP) is HOTP evaluated at a clock-derived counter. This tool follows the two standards exactly — RFC 6238 for the time step and RFC 4226 for the HMAC and truncation — computing everything locally with the browser's Web Crypto API. The secret never leaves your device.

  1. Decode the secret. The Base32 string (RFC 4648 §6, alphabet A–Z and 2–7) is decoded to the raw key bytes K. Lower-case, spaces, hyphens and = padding are tolerated.
  2. Compute the time step. T = floor((now − T0) / X) with T0 = 0 and X = period (default 30 s). T is encoded as an 8-byte big-endian integer.
  3. HMAC. H = HMAC-Hash(K, T), where Hash is SHA-1, SHA-256 or SHA-512. This is a 20-, 32- or 64-byte value.
  4. Dynamic truncation (RFC 4226 §5.3). Let offset = H[last byte] & 0x0F. Take the 4 bytes at that offset and mask the top bit: binCode = (H[offset] & 0x7F)≪24 | H[offset+1]≪16 | H[offset+2]≪8 | H[offset+3].
  5. Reduce to digits. OTP = binCode mod 10^digits, left-padded with zeros. For 6 digits that is mod 1,000,000.

The derivation panel inside the tool shows every one of these intermediate values for the current code, so you can line them up against your own implementation byte for byte. On load, the tool also recomputes the official RFC 6238 Appendix B test vectors for SHA-1, SHA-256 and SHA-512 and confirms each matches — that is the “RFC 6238 verified” badge. To create a new account, the “New secret + QR” tab draws a 160-bit key from crypto.getRandomValues and assembles a Google Key-Uri-Format otpauth://totp/… URI rendered as a QR code.

Worked examples

RFC 6238 vector — T0 window

Secret GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ · SHA-1 · period 30 · Unix 59

  1. Time step: T = floor(59 / 30) = 1 → 0x0000000000000001
  2. HMAC-SHA-1(K, T) → 20-byte digest
  3. Dynamic truncation → 31-bit binCode = 1094287082
  4. 8 digits: 1094287082 mod 10^8 = 94287082
  5. 6 digits: 1094287082 mod 10^6 = 287082

RFC 6238 vector — later window

Same secret · SHA-1 · period 30 · Unix 1,111,111,109

  1. Time step: T = floor(1111111109 / 30) = 37037036 → 0x00000000023523EC
  2. HMAC-SHA-1(K, T) → dynamic truncation
  3. 8 digits → 07081804
  4. 6 digits → 081804
  5. Both match RFC 6238 Appendix B exactly.

Demo secret cross-check (edge: Unix 0)

Secret JBSWY3DPEHPK3PXP · SHA-1 · 6 digits · period 30 · Unix 0

  1. Time step: T = floor(0 / 30) = 0 → 0x0000000000000000
  2. HMAC-SHA-1(K, 0) → dynamic truncation → mod 10^6
  3. Result: 282760
  4. This is the value otplib and pyotp return for TOTP('JBSWY3DPEHPK3PXP').at(0),
  5. a second reference point independent of the RFC vectors.

Frequently asked questions

Sources & references

The algorithm on this page was last cross-checked against the RFC 6238 Appendix B test vectors (SHA-1, SHA-256 and SHA-512) and the otplib/pyotp demo-secret value on 2026-07-15. The check re-runs in your browser every time the tool loads.

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found a bug, edge case, or want to suggest an improvement?

Email me at [email protected] — most fixes ship within 24 hours.