/^/
EasySecurity3 min read

One-Time Password (OTP) Regex

Validates that a string is a numeric one-time password between 4 and 8 digits long, matching the typical range used by SMS, email, and authenticator-app OTPs.

#otp#security#validation#2fa#authentication#numeric

Regex Pattern

^\d{4,8}$

Pattern Breakdown

Hover over a token to see what it does.

^\d{4,8}$
TokenMeaning
^Anchors the match to the start of the string
\dMatches a single digit (0-9)
{4,8}Requires between 4 and 8 digits, the common length range for OTPs
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern checks that the entire input string consists only of digits and is between 4 and 8 characters long, matching the shape of a typical numeric one-time password sent via SMS, email, or generated by an authenticator app.

Why it works

Most OTP schemes (TOTP/HOTP per RFC 6238/4226, and most SMS-based codes) generate a fixed-length numeric string, commonly 6 digits but sometimes as short as 4 or as long as 8. A simple bounded digit-count quantifier captures this whole common range without needing to know the exact length a given provider uses.

Common use cases

  • Validating the shape of a code entered into a 2FA/OTP input field before checking it against the server
  • Client-side format checks to give instant feedback before an OTP verification API call
  • Filtering SMS message text to auto-extract a likely OTP code for autofill
  • Rejecting obviously malformed input (letters, wrong length) before spending a verification attempt

Edge cases

  • Codes with leading zeros, like '0042', are valid OTPs and are correctly matched since \d treats them as ordinary digits, not numbers
  • Alphanumeric OTPs (some systems mix in letters) will not match this numeric-only pattern and need a separate pattern
  • A code of exactly 4 or exactly 8 digits is accepted since the quantifier bounds are inclusive
  • Whitespace around the code, like ' 123456', is rejected due to the anchors

Limitations

  • Only validates shape, not correctness; the actual OTP must still be verified server-side against the expected value and expiry window
  • Does not enforce a single fixed length; if your system always uses exactly 6 digits, a tighter {6} pattern is more precise
  • Does not support alphanumeric or hyphenated OTP formats used by some providers
  • Cannot detect or prevent OTP brute-forcing; rate limiting must be handled separately

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

1234 123456 12345678

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const otpRegex = /^\d{4,8}$/;
console.log(otpRegex.test('123456')); // true

Common Mistakes

Treating a format-valid OTP string as an already-verified code

Fix: Always check the entered code against the server-generated value and its expiry window; regex only validates shape

Using a fixed {6} when the product actually supports variable-length OTPs across providers

Fix: Use the {4,8} range (or your exact supported lengths) so the input field doesn't reject valid shorter or longer codes

Allowing unlimited verification attempts because 'the regex passed'

Fix: Rate-limit and lock out OTP verification attempts server-side regardless of client-side format validation

Performance Notes

  • A single bounded digit quantifier is O(n) with no backtracking risk
  • This pattern is cheap enough to run on every keystroke for live input-field validation feedback
  • Anchors ensure the whole field content is checked, not just a leading digit run

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes