# How the 6-digit code in your authenticator app works (TOTP explained)

> Your phone shows a six-digit code that changes every 30 seconds and the website somehow knows it, with no internet connection between the two. The trick is a shared secret and a shared clock. This guide walks through exactly what happens, how safe it is, and where it still fails.

Published 2026-10-08 by Toolcloak. 6 minute read. Original: https://toolcloak.pages.dev/articles/how-the-6-digit-code-in-your-authenticator-app-works-totp-explained
Related free tool: [TOTP Code Generator](https://toolcloak.pages.dev/tools/totp-generator)

When you turn on two-factor authentication, a site shows you a QR code. You scan it once with an authenticator app, and from then on the app displays a six-digit number that changes twice a minute. You type it in, and you are let through. The app never talks to the site. So how do both sides arrive at the same number? The answer is a small, elegant recipe called TOTP.

> **In short**
> - **TOTP** (time-based one-time password) mixes a **shared secret** with the **current time** to produce a short code.
> - The secret is sent **once**, in the QR code. After that, your phone and the server each compute the code on their own.
> - The time is cut into **30-second steps**. The code only changes when the step number changes.
> - A random guess succeeds about **1 time in a million** per try, so rate limits matter. TOTP is far better than a password alone, but it **can still be phished**.

## The two ingredients

TOTP, defined in an open standard (RFC 6238), needs only two things that both sides already have: a **secret key** and the **clock**. The secret is a random string chosen by the server when you set up 2FA. The QR code you scan is just that secret, plus a label for the account, written in a way the app can read. The app stores it and the server stores it. That is the only moment the secret travels.

The clock is the second ingredient. Phones and servers keep time closely synchronised through the internet, so both can agree on “what time is it now” to within a second or two without talking to each other.

**What each side holds**

| Your phone | The website |
| --- | --- |
| Secret + clock | Secret + clock |
| Stored the secret when you scanned the QR | Stored the same secret for your account |
| Reads the current time from the phone | Reads the current time from the server |
| Works with no signal at all | Computes the code it expects and compares |

*Same inputs on both sides give the same output. That is why the app works in airplane mode.*

Try it: [TOTP Code Generator](https://toolcloak.pages.dev/tools/totp-generator). Paste a secret and see the live code and the seconds left. Use test secrets only, never your real account secret on a site you do not trust.

## From time to a counter

The first step is to turn the time into a whole number that changes only every 30 seconds. Take the Unix time (the seconds since 1 January 1970; see [Unix time explained](https://toolcloak.pages.dev/articles/unix-time-the-number-that-counts-seconds-since-1970)) and divide by 30, dropping the fraction. The result is the **counter**.

> **counter = floor(Unix time ÷ 30):** At Unix time 1,700,000,010 the counter is 56,666,667. It stays 56,666,667 for the next 30 seconds and becomes 56,666,668 at 1,700,000,040.

**Three moments and the counter they produce**

| Unix time | Counter | Same code as the first? |
| --- | --- | --- |
| 1,700,000,010 | 56,666,667 | Yes (start) |
| 1,700,000,039 | 56,666,667 | Yes (29 s later) |
| 1,700,000,040 | 56,666,668 | No, a new code |

**One 30-second step**

| When | What |
| --- | --- |
| 0 s | A new code appears. The counter just ticked up, so the app computes a fresh code. |
| 15 s | Halfway. The same code is shown. You have comfortable time to type it. |
| 25 s | Time is short. Many apps show the ring turning red. Wait for the next code if you are slow. |
| 30 s | Next step. The counter becomes N + 1 and the old code stops being the current one. |

## From counter and secret to six digits

Now the counter and the secret are mixed using **HMAC**, a keyed hash (the idea is explained in [what a hash is](https://toolcloak.pages.dev/articles/what-a-hash-is-and-why-changing-one-letter-changes-everything)). A hash scrambles its input so thoroughly that even a tiny change gives a completely different output, and HMAC adds the secret so that only someone who knows it can produce the same result. The output is a long block of bytes, much too long to type.

So the standard shrinks it with a step called **dynamic truncation**: look at the last byte, use its low four bits as a starting position, take four bytes from that position, drop the top bit, and read them as a number. Finally take that number modulo 1,000,000 (the remainder after dividing) to get exactly six digits, padding with zeros at the front if needed.

**The whole recipe**

1. **Read the clock.** Unix time, for example 1,700,000,010.
2. **Make the counter.** Divide by 30 and drop the fraction: 56,666,667.
3. **Mix with the secret.** Run HMAC over the counter using the shared secret (SHA-1 by default in most apps).
4. **Truncate.** Pick four bytes from a position chosen by the last byte of the result.
5. **Keep six digits.** Take the number modulo 1,000,000 and pad with leading zeros.

*You never need to do this by hand. The point is that every step is public and repeatable, and only the secret is private.*

> **Why the secret looks like “JBSWY3DPEHPK3PXP”:** Secrets are usually shown in Base32, a text format with 32 symbols (capital letters and digits 2 to 7), chosen to avoid confusing characters. Each Base32 character carries 5 bits, so a 16-character secret holds 80 bits and a 32-character one holds 160 bits. Compare the encoding step with the [Base32 encoder](https://toolcloak.pages.dev/tools/base32-encoder).

## How safe is a six-digit code?

There are only 1,000,000 possible six-digit codes, so a blind guess has a 1 in a million chance. That sounds weak, and by itself it would be, but the code is never the only barrier. It works together with a password, and servers limit attempts. Because clocks drift slightly, servers usually accept the previous, current and next step, so three codes are valid at once: the odds of a lucky guess become about 3 in a million.

**Odds of guessing blindly**

|  | Value | Note |
| --- | --- | --- |
| One try, one valid code | 1 in 1,000,000 | Six digits, 10⁶ possibilities |
| One try, three valid codes | 1 in 333,333 | With a ±1 step grace window |
| Five tries in a row | 1 in 66,667 | Without a lockout, 5 × 3 in a million |

*Real services lock the account or slow down after a handful of wrong codes, so an attacker cannot simply try hundreds of thousands of codes.*

**What TOTP protects against, and what it does not**

| Box | What it means |
| --- | --- |
| Stolen password | A leaked password alone is no longer enough. The attacker also needs the code. |
| Reused password in a breach | Other sites’ leaks cannot unlock this account without your phone. |
| Real-time phishing | A fake site can ask for your code and pass it on within 30 seconds. TOTP does not stop this. |
| Lost or wiped phone | Without a backup, you may be locked out yourself. Save the recovery codes. |

*TOTP is a strong everyday layer, not a perfect one. Hardware keys and passkeys, which are tied to the real site address, resist phishing better.*

## TOTP, SMS codes and passkeys

Text-message codes are easy to use but depend on your phone number, which can be hijacked through SIM-swap fraud or intercepted, and on the network being available. TOTP codes are generated on your device and need no signal. Passkeys and hardware security keys go further by cryptographically tying the login to the site, so a copied page cannot trick you.

**Rough comparison of second factors**

| Method | Works offline | Hard to phish | Easy to set up |
| --- | --- | --- | --- |
| SMS code | No | No | Very easy |
| Authenticator app (TOTP) | Yes | No | Easy |
| Passkey or hardware key | Yes | Yes | Moderate |

None of these is useless. Any second factor is far better than none, because most account takeovers rely on a stolen or guessed password. If you can choose, use an authenticator app over SMS and a passkey over an app. For the password side of the equation, see [password entropy](https://toolcloak.pages.dev/articles/password-entropy-bits-guesses-and-why-length-beats-symbols).

## Practical habits

1. **Save the recovery codes** when you set up 2FA, and keep them somewhere other than your phone.
2. **Back up the secret** if your app offers encrypted backup, or note the setup key in a password manager.
3. **Keep your phone’s clock automatic.** If the codes are rejected, a wrong clock is the first thing to check.
4. **Never share the code**, even with someone who says they are from support. A valid code is a key to your account for 30 seconds.
5. **Check the address bar** before typing a code into any site.

The cleverness of TOTP is how little it needs: one secret, shared once, and the clock that is already on every device. Try the generator above with a test secret and watch the code change at the 30-second mark. It is the same maths protecting accounts all over the internet.

## Frequently asked questions

### What does TOTP stand for?

Time-based One-Time Password. It generates a short code from a shared secret and the current time, defined in RFC 6238.

### How does the app know the code without internet?

The app and the server share a secret and both use the clock. They each compute the same code independently, so no connection is needed at login time.

### Why does the code change every 30 seconds?

The time is divided into 30-second steps and the code is derived from the step number. When the step number changes, so does the code.

### Why does my code say it is invalid?

The most common cause is a wrong phone clock. Turn on automatic date and time. Also check that you typed the current code, not the one that just expired.

### Is an authenticator app safer than SMS?

Generally yes. App codes are generated on your device and cannot be intercepted through your phone number. Neither one stops a real-time phishing page.

### What happens if I lose my phone?

You need your recovery codes or a backup of the secret to get back in. Save these when you enable 2FA, and keep them away from the phone.

