TOTP Code Generator
Generate the six-digit codes an authenticator app would show, from the same secret the server holds. Paste a Base32 secret or the full otpauth:// enrolment URI, choose the hash and digit count if they differ from the defaults, and read the current code, the seconds left in its time step, and the codes for the neighbouring steps.
The page exists for developers who are implementing or debugging two-factor login. Enrol a test account against your own server, paste the secret here, and check that your verifier accepts the code this page produces. Use a secret made for testing, not one that guards a real account.
How a TOTP code is computed
RFC 6238 builds on RFC 4226 (HOTP). Both sides share a secret, usually 20 bytes delivered as a Base32 string. The current Unix time is divided by the period, 30 seconds by default, to produce an integer step counter. That counter is encoded as 8 big-endian bytes and signed with HMAC using the shared secret.
The HMAC output (20 bytes for SHA-1) is then truncated. The low four bits of the last byte select an offset; the four bytes starting at that offset are read as a 31-bit integer, and that integer modulo 10^digits is the code, left-padded with zeros. The same arithmetic, with the same inputs, gives the same code on a phone, a hardware token and a server.
The window pane shows this directly: each row is one step counter with its UTC start time and the code it yields. Codes change at the period boundary, not at a fixed wall-clock second, so a 30-second period changes codes at :00 and :30 of every minute.
The otpauth URI
Enrolment QR codes carry a URI in this shape:
otpauth://totp/Example:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=SHA1&digits=6&period=30
The host is the type (totp or hotp), the path is the label (issuer:account), and the query holds the secret and settings. algorithm, digits and period are optional and default to SHA1, 6 and 30. HOTP URIs carry counter instead of period. Paste one here, or upload the QR image, and every field is applied.
Why codes disagree
Three settings and one clock are all that can differ between two implementations.
- Algorithm: a server configured for SHA-256 produces codes that never match a SHA-1 client. Most consumer authenticator apps use SHA-1 regardless of what the URI says.
- Digits: the truncation step keeps the last 6, 7 or 8 decimal digits. A code of the wrong length is rejected outright.
- Period: a 60-second server with a 30-second client agrees only half the time.
- Clock: a device 40 seconds behind computes the previous step. Servers accept a code from one step either side for this reason, and the window pane shows those neighbours so a drift problem is visible as a code one row away.
HOTP mode
Switch to HOTP to work with counter-based tokens. The counter is shared via the URL so a test sequence can be reproduced. “Next counter” advances it by one, matching what a hardware token does on each button press. A server that fell behind by several presses resynchronises by searching forward through a look-ahead window; the window pane here shows the same range.
Secret handling
The secret is held in page memory only. It is not written to the URL, local storage, or any request; refreshing the page clears it. The remaining settings are in the URL so a colleague can open the same configuration and paste their own secret. The QR image upload is decoded on a canvas inside the page and the image is discarded once the URI has been read.