🔢 TOTP / 2FA Code Generator
Live 6-digit codes from any TOTP secret — no phone needed.
Paste the base32 secret from your QR code or app settings. Spaces and lowercase are OK.
Current OTP
What Is TOTP and How Does a 6-Digit Code Get Generated in Milliseconds?
Every time you open Google Authenticator, Authy, or Microsoft Authenticator and see a six-digit number counting down, you are watching a tiny mathematical machine called TOTP — Time-based One-Time Password — running inside your phone. The code changes every 30 seconds, it cannot be reused, and it is generated entirely offline without talking to any server. Understanding how it works helps you debug it, test it, and trust it. This guide walks through the full process, step by step, from secret key to glowing digits.
The Foundation: HMAC-SHA1 and Why It Works
TOTP is built on top of HOTP (RFC 4226), which itself is built on HMAC-SHA1. HMAC stands for Hash-based Message Authentication Code. SHA-1 is the underlying hash function. Together they produce a 20-byte (160-bit) fingerprint of a message that is virtually impossible to reverse or forge without knowing the secret key.
Here is what makes TOTP clever: both you and the server share one secret key, established when you first scan the QR code. After that, neither side ever transmits the key again. Instead, at login time, your phone and the server independently compute HMAC-SHA1 over the same input — the current 30-second time window — and both arrive at the same six-digit answer. If the answers match, you are authenticated. No network call needed. No password sent over the wire.
Step 1 — Decode the Base32 Secret
When a website gives you a TOTP secret, it looks like JBSWY3DPEHPK3PXP or similar. This is the raw key encoded in Base32, a character set using only the 26 letters A–Z and the digits 2–7. Base32 avoids confusable characters like 0 (zero) and O (letter O) or 1 and l, which makes it safe to read aloud or type from a screen.
To use the key, you decode Base32 back to raw bytes. Each Base32 character encodes exactly 5 bits, so every 8 characters produce 5 bytes. The decoding process groups bits, shifts them into a byte accumulator, and emits a full byte every time 8 bits accumulate. In JavaScript this runs in plain client-side code with no libraries required.
Step 2 — Convert Unix Time to a Counter
TOTP introduces the time dimension by converting the current Unix timestamp (seconds since 1970-01-01 UTC) into a rolling counter:
counter = Math.floor(Date.now() / 1000 / 30)
Dividing by 30 means the counter value stays the same for an entire 30-second window, then increments by exactly one. Because both your device and the server use the same UTC clock — within a few seconds of each other — they land on the same counter value and therefore compute the same OTP. This is why TOTP works even when your phone has no internet: the secret and the time are all the information needed.
The counter is expressed as an 8-byte big-endian integer so that regardless of the platform's integer size, the byte order is always predictable and RFC-compliant.
Step 3 — Compute HMAC-SHA1
You now have two things: the secret key bytes and the 8-byte counter. Feeding both into HMAC-SHA1 produces a 20-byte output:
hmac = HMAC-SHA1(key = secretBytes, message = counterBytes)
In modern browsers, the Web Crypto API handles this natively and securely via crypto.subtle. You import the key bytes as a CryptoKey object with the HMAC/SHA-1 algorithm, then call crypto.subtle.sign(). The whole operation is asynchronous and runs in a separate secure thread inside the browser — the key material never touches your JavaScript memory longer than necessary.
Step 4 — Dynamic Truncation to 6 Digits
HMAC-SHA1 returns 20 bytes, but you only want 6 digits. The algorithm uses a technique called dynamic truncation to extract a 4-byte slice and turn it into a number:
- Read the last nibble (4 bits) of byte 19:
offset = hmac[19] & 0x0f. This gives a value 0–15. - Take 4 consecutive bytes starting at that offset.
- Mask off the top bit of the first byte (to ensure a positive 31-bit number):
byte[0] & 0x7f. - Combine the 4 bytes into a single 32-bit integer using bit-shifting.
- Take that number modulo 1,000,000 to get a 6-digit value, zero-padded on the left if necessary.
The dynamic offset makes truncation unpredictable — an attacker who sees the OTP cannot deduce information about the underlying HMAC output because different parts of the 20-byte result are used for different time windows.
Step 5 — Live Countdown and Auto-Refresh
To show a live authenticator experience in the browser, the widget runs a setInterval every second. Each tick it recomputes the seconds remaining in the current 30-second window (30 - (unixSeconds % 30)) and updates the progress bar. When the counter increments — i.e., when the window boundary crosses — a new TOTP is computed automatically and the code display updates with a brief colour transition so you notice the refresh.
This is exactly what your phone's authenticator app does, except it runs natively. The mathematics are identical, which means codes generated here will always match your authenticator app for the same secret and the same 30-second window.
How to Use This Tool for Testing and Debugging
Testing a new TOTP integration: When you add TOTP to your own website or API, paste the generated secret into this tool alongside your authenticator app. Both should show the same code at the same moment. If they differ, your secret encoding or your HMAC implementation has a bug.
Verifying clock skew: TOTP servers typically accept the current window plus one window in either direction (±30 seconds tolerance). If your code keeps failing, your system clock may be drifting. Check date in your terminal or sync with an NTP server.
Recovering access during device migration: If you are migrating authenticator apps, paste the secret here temporarily to confirm the codes match before removing the old entry.
Developer CI testing: Automated tests that exercise a 2FA login flow need to generate the current TOTP programmatically. The same base32-decode + HMAC-SHA1 + truncate algorithm shown here works in any language — Python, Node.js, Go, Ruby — using the standard HMAC and base32 libraries in each ecosystem.
Security Considerations
TOTP secrets are permanent. Unlike the OTP codes themselves, the secret key never expires. Anyone who obtains your secret can generate valid codes indefinitely. Treat your secret with the same care as a password. Do not screenshot it, do not paste it into untrusted websites, and do not store it in plain text.
This tool runs entirely in your browser. No secret you enter here leaves your machine — there is no server, no logging, no analytics. The source code is visible in the page: open DevTools and inspect it any time.
If you are building a service that issues TOTP secrets to users, store the secrets encrypted at rest. Use a proper key management service or at minimum encrypt with a hardware security module-backed key. On the authentication side, implement rate limiting and lockout to prevent brute-force attacks against the 1,000,000 possible code values.
TOTP vs SMS OTP: Why TOTP Wins
SMS-based one-time passwords suffer from SIM-swapping attacks, where an attacker socially engineers your carrier into transferring your phone number to their SIM card. Once they have your number, they intercept your SMS codes. TOTP has no such weakness because the secret never travels over the phone network — it lives only in the authenticator app and on the server database. TOTP is also faster (no SMS delivery delay), works offline, and is free.
The main drawback of TOTP is recovery: if you lose your phone without a backup of the secret, you may be locked out permanently. Always save your backup codes when enabling 2FA, and consider storing TOTP secrets in a password manager that supports TOTP fields.
Compatible Services and Apps
TOTP per RFC 6238 is supported by virtually every major platform that offers 2FA: Google, GitHub, AWS, Cloudflare, Stripe, Discord, Binance, and hundreds more. Any service that shows you a QR code or a base32 secret string during 2FA setup is using TOTP. The codes generated here are identical to those from Google Authenticator, Authy, Bitwarden, 1Password, Apple Passwords, and any other standards-compliant app — because the algorithm is specified by an open RFC, not by any single vendor.