Starting points for your own code. Run them in the environment shown below.
Node.js 22+ · ES module (.mjs)
Current inputs apply only to fields used by the example. Selected files are not embedded.
Install dependencies
import { createHmac } from "node:crypto";
// RFC 6238 test secret (ASCII bytes). Real Base32 secrets must be decoded first.
const secret = Buffer.from("12345678901234567890", "ascii");
function totp(unixSeconds, digits = 6) {
const counter = Buffer.alloc(8);
counter.writeBigUInt64BE(BigInt(Math.floor(unixSeconds / 30)));
const hash = createHmac("sha1", secret).update(counter).digest();
const offset = hash.at(-1) & 15;
const number = hash.readUInt32BE(offset) & 0x7fffffff;
return String(number % 10 ** digits).padStart(digits, "0");
}
console.log(totp(59, 8)); // 94287082
console.log(totp(Math.floor(Date.now() / 1000)));
Put it to work
Generate and verify test OTPs with a Base32 secret.
Details that matter
Format and meaning
Verification allows ±1 time step. Current-time mode calculates when run and does not synchronize with a server.
Supported scope and limits
Text 1 MB
Split inputs that exceed the limit. If a format or algorithm is unsupported, choose a tool that matches your requirements instead of silently changing the format.