hotp · rfc 4226 · counter-based · local

Generate HOTP codes by counter

Counter-based one-time passwords for hardware tokens and offline devices. Advance the counter manually, copy the 6-digit code. Computed entirely in your browser.

HOTP Generator
Counter
0
current
Digits
6
rfc 4226
Algorithm
HMAC-SHA1
standard
Status
ready
live
Counter:
input · secret

HOTP codes advance by counter, not by time. Use Next code to step forward. Reset to 0 to start over.

output · 6-digit code
------
counter = 0
Quick Start

How to generate HOTP codes

HOTP (RFC 4226) is the counter-based ancestor of TOTP. Each Next code increments the counter and re-derives a new 6-digit value from your shared secret.

  1. 01

    Paste base32 secret

    The shared secret your token was enrolled with.

    Inputs are treated as UTF-8 throughout the pipeline and validated client-side as you type — nothing dispatches until the value is well-formed.

    secretinpututf-8client-sidevalidated
    secret · textbase32 · set
    JBSWY3DPEHPK3PXP
    loaded · parsedclient-side
  2. 02

    Set counter

    Match the server's current counter, or 0 if just enrolled.

    Each toggle re-computes through a memoised hook, so flipping options never resets your input and the UI stays snappy on large inputs.

    counteroptionslivememoisedtoggles
    counter · memoised0 · live
    counter = 0
    options set · memoisedlive
  3. 03

    Read code

    HMAC-SHA1 over the counter, truncated to 6 digits.

    Randomness — where used — comes from crypto.getRandomValues, never Math.random. Heavy work sits in useMemo.

    codecomputeinstantlocaldeterministic
    code · instant6 digits · computed
    287082
    computed · instantinstant
  4. 04

    Advance

    Click Next code after each successful auth so counters stay in sync.

    Copy writes through navigator.clipboard and downloads use a Blob — zero network traffic. Same input plus same options always yield the same bytes.

    synccopydownloadzero-networkreproducible
    ok · copiednext · copied
    counter += 1
    shipped · ready to shipsuccess
Pro tips

Pro tips for everyday utilities

Reach for crypto.getRandomValues

Cryptographically random for IDs, tokens, salts. Math.random is for animation and games, not security.

Sort IDs lexicographically

UUID v4 has no time ordering. Use ULID or UUID v7 if you need sorted IDs.

Mock data with seeds

Faker-style libraries can be seeded so tests are reproducible. Embed the seed in the fixture file.

Reference cards beat memory

Cheatsheets for Vim, Git, Docker, Linux signals are faster than man pages when you’re mid-flow.

Browser APIs vary

Touch events, gamepads, and clipboard differ across vendors. Feature-detect before use.

Persist in the right place

localStorage for user preferences, sessionStorage for transient state, IndexedDB for structured data.

Use Cases

When to use HOTP

Hardware tokens, offline auth, legacy systems.

Hardware tokens

YubiKey OATH-HOTP and other counter-based tokens. Random values come from crypto.getRandomValues — cryptographically secure for tokens, salts, and session IDs. Math.random is deterministic enough for animations but predictable enough to be a security bug.

CSPRNG-backed

Offline auth

Devices with no reliable clock — counters survive power loss. Pair with hashids, ULID, or UUID v7 when you need both random and sortable — useful for primary keys, public-facing IDs, and event log ordering without a sequence column.

reproducible

Legacy systems

Older deployments that pre-date TOTP. Output is deterministic given the same seed, so fixtures and tests stay reproducible across CI runs and contributor machines. Embed the seed in the fixture file for full replay.

snappy

Single-shot codes

Email-delivered codes that should not re-roll on timer. Heavy work runs through useMemo so the UI stays snappy on large inputs. Same input + same options yields identical bytes — the kind of stability snapshot tests rely on.

feature-detected

Test fixtures

Deterministic codes for unit and integration tests. Storage tools persist to the right backend: localStorage for user preferences, sessionStorage for transient state, IndexedDB for structured data. Pick the right shelf and quota worries disappear.

deterministic

Education

Learn the HMAC-SHA1 derivation underlying TOTP. Browser feature detection: clipboard, fullscreen, gamepad, and Web Bluetooth APIs gracefully fall back when unavailable. No surprise white screens on Safari or older Firefox.

production-ready
FAQ

Frequently asked questions

TOTP uses the current Unix time / 30 as the counter — automatically rolling. HOTP uses an explicit counter that you advance per code.
Most servers accept a window of N codes ahead of their counter to catch up automatically.
RFC 4226 supports 6 to 8 digits. This tool uses 6 — the most common length.
Yes, for HOTP/TOTP purposes. The output is truncated to 31 bits + mod, so collisions are bounded.
No. HOTP codes are derived locally in your browser via Web Crypto. Nothing leaves the page.
Suggest a tool

Something missing?

Tell us what you need. We ship the top requests every two weeks.

Sent straight to the maintainers · no account needed
47 in queue·8 shipped this month
Request queued. Thanks!