TOTP Authenticator Code Generator

Generate the same time-based codes an authenticator app produces from a Base32 secret, useful for testing and for understanding how the scheme works.

Generates the same six-digit codes an authenticator app would, so you can check a secret works before you rely on it. Everything stays in this tab — nothing is saved or sent anywhere.

------

Next and previous codes

Servers usually accept the neighbouring code too, to allow for clock drift.

Eight digits is a hundred times safer and a hundred times less uniform

A TOTP code is a 31-bit number — 2,147,483,648 possibilities — reduced with a modulo into a decimal range that does not divide it. The remainder has to go somewhere, so some codes come up more often than others.

DigitsPossible codesCodes appearing more oftenCodes appearing less oftenBias
6 1,000,000 483,648 × 2,148 516,352 × 2,147 0.0466%
7 10,000,000 7,483,648 × 215 2,516,352 × 214 0.4673%
8 100,000,000 47,483,648 × 22 52,516,352 × 21 4.7619%

Every code is accounted for and every one of the 2,147,483,648 outcomes lands somewhere — the two columns multiply out to exactly 231. The bias gets ten times worse with each digit added, because the same 231 is cut into ten times as many bins. At six digits it is 0.047%; at eight, some codes are 4.8% likelier than others. Going from six digits to eight multiplies the search space by 100 and the bias by about 102 — the same factor, pulling opposite ways. It is not a practical weakness, since an attacker who knew which codes were favoured would still be searching 100,000,000 of them. It is a real property of the standard, and it runs against the intuition that more digits is uniformly better. No digit count divides 231 evenly, so there is no setting that removes it.

The 30-second code is valid for 90

Clocks drift, so nearly every verifier accepts the previous and next steps as well as the current one — which is exactly why this page shows you 3 codes rather than one. The consequence is that a 30-second code has a 90-second life, and the target an attacker is shooting at is 3 times the width of the progress bar above. Each further step of tolerance a server allows adds two more valid codes, not one.

Attempts allowedExpected time to guess a 6-digit code
1 per second 5.8 days
10 per second 13.9 hours
100 per second 1.4 hours

With a million six-digit codes an attacker averages 500,000 attempts. Which is the whole argument in one line: the digits are not the defence, the rate limit is. Six digits at three attempts a minute holds for 116 days; eight digits with no limit at all falls in 5.8 days. The rate limit is worth about 20 times what the two extra digits are.

That 5.8 days is the same figure as the first row of the table, and not by accident: a hundred times as many codes attacked a hundred times as fast takes exactly as long. Two extra digits buy you nothing at all against an attacker who is merely allowed to try harder.

A Base32 secret is not always a whole number of bytes

Base32 carries five bits per character and a key is made of whole bytes, so a secret only converts cleanly when its length is a multiple of eight characters.

Secret lengthBitsKey bytesBits left over
1 character 5 0 5
8 characters 40 5 none
16 characters 80 10 none
20 characters 100 12 4
26 characters 130 16 2
32 characters 160 20 none

The usual 16-character secret is 80 bits, exactly 10 bytes, and the longer 32-character one is 160 bits. Both are clean. Anything else leaves a few bits stranded at the end. A one-character secret is five bits, which is no bytes at all — so the browser's crypto refuses it outright with "Zero-length key is not supported". That message is perfectly true and explains nothing to somebody who has typed a single letter into a box, so: 2 characters is the shortest secret that produces any key material, and 16 is the shortest anyone should use.

How to use

  1. Enter your Base32 secret.
  2. Read the current code and the seconds remaining.
  3. Compare against your authenticator app to confirm they match.
  4. Do not use this as a replacement for a real authenticator.

Frequently asked questions

How does TOTP work?

The server and your device share a secret. Both compute an HMAC of that secret and the current time divided into 30-second intervals, then reduce it to six digits. Because both sides derive the same value independently, nothing needs to be transmitted — which is why authenticator apps work offline.

Why do codes change every 30 seconds?

Because the time interval is part of the input. Thirty seconds is the conventional window, balancing usability against how long a stolen code stays valid. Servers usually accept the adjacent windows too, to tolerate clock drift and slow typing.

Why is my code rejected?

Almost always clock skew. TOTP depends on both sides agreeing what time it is, so a device clock several minutes out generates codes for the wrong window. Enabling automatic time synchronisation resolves the great majority of these cases.

Should I use this instead of an authenticator app?

No. It is a testing and learning tool. A real authenticator stores the secret in your device's secure hardware; pasting a secret into a web page puts it in browser memory, in your clipboard, and possibly in your paste history. Use it to understand or debug the scheme, not to hold live credentials.

Is TOTP better than SMS codes?

Considerably. SMS is vulnerable to SIM swapping and to interception in the phone network, and it depends on the carrier. TOTP secrets never leave your device after enrolment and work without signal. Hardware security keys are stronger still, since they also resist phishing, which TOTP does not.

Can a TOTP code be phished?

Yes, and this is its main weakness. A convincing fake login page can ask for the code and relay it to the real site within the 30-second window. Hardware keys using WebAuthn defeat this because they verify the site's origin cryptographically, and a code typed by a human cannot.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.