Skip to content
T
Tools.Town
Free Online Tools for Everyone
Calculators

Verhoeff Algorithm Explained: How Aadhaar Detects Typos

The 12th digit of every Aadhaar number is a Verhoeff check digit. Learn how this 1969 algorithm catches almost every single-digit typo and most digit swaps — the same math you can verify yourself in our Aadhaar Format Validator.

16 May 2026 4 min read By Tools.Town Team Fact Checked

Key Takeaways

  • Luhn (the algorithm credit cards use) catches all single-digit errors and most adjacent transpositions, but misses two specific transposition cases (09 ↔ 90 swaps in some configurations)
  • No algorithm catches every possible error — only 9 in 10 of 'random' multi-digit errors are caught by any single check digit
  • It's the check digit on German bank routing numbers (BLZ) in some configurations, on Indian primary education identifiers, and increasingly on identity numbers in countries that learned from credit-card Luhn-collision incidents
  • No

What problem does a check digit solve?

You’re typing a 12-digit Aadhaar into a KYC form. You hit the wrong key on digit 7. Without a check digit, the form has no way to know — it accepts your number and ships it to the backend, where some downstream system either rejects it three steps later, or worse, accepts it and matches the wrong person.

A check digit is a single extra digit appended to a number so that the number “checks itself”. Change any digit and the math no longer adds up. The form catches the error at the keystroke, not three systems away.

The most famous check digit is the last digit of every credit card number, which uses the Luhn algorithm. Indian Aadhaar, designed in 2009 for what was about to become the world’s largest identity system, picked something stronger: Verhoeff.

Why Verhoeff over Luhn?

Luhn is simpler, but it has a few blind spots. Specifically, Luhn detects:

  • 100% of single-digit substitution errors
  • ~90% of single-digit transposition errors (it misses the swap pair 09 ↔ 90)

Verhoeff, invented by Dutch mathematician Jacobus Verhoeff in 1969, fixes the gap. It detects:

  • 100% of single-digit substitution errors
  • 100% of single-digit transposition errors — every adjacent swap
  • The vast majority of more exotic two-digit errors (twin errors, jump twin errors, etc.)
100%
Single-digit substitutions caught
100%
Adjacent transpositions caught
~95.5%
Phonetic errors caught (vs ~90% Luhn)

For credit cards, where the consequence of a missed typo is “user retries the form”, Luhn is fine. For Aadhaar, where the consequence is “wrong person gets matched to a benefit, a SIM, a bank account, or a vaccine record”, the extra coverage matters.

Verhoeff isn’t harder math — it’s the same idea as Luhn (sum with weights, mod 10) but expressed through the dihedral group D₅ instead of plain addition. The group has the property that multiplication is non-commutative, which is exactly what kills transposition blind-spots.

How it works

Verhoeff uses two precomputed 10×10 tables:

  • D — a multiplication table for the dihedral group D₅ (the symmetries of a regular pentagon).
  • P — a permutation table that “rotates” digit positions, so position matters and 12 ≠ 21.

The algorithm walks the digits from right to left. At each position i, it:

  1. Looks up P[i mod 8][digit] — the position-specific permutation of the digit.
  2. Multiplies the running value c by that permuted digit using table D.
  3. Stores the result back in c.

When all 12 digits are processed, the number is valid if and only if c ends at 0.

function verhoeffValid(digits) {
let c = 0;
const reversed = digits.split('').reverse();
for (let i = 0; i < reversed.length; i++) {
  const n = parseInt(reversed[i], 10);
  c = D[c][P[i % 8][n]];
}
return c === 0;
}

The full D and P tables are 200 numbers total. Once you have them in code, validation is O(n) over the digit count — fast enough to run on every keystroke without a debounce.

Open the Aadhaar Format Validator and type any 12-digit number starting with 2–9. The Verhoeff check row in the checklist flips red the instant the math breaks — including when you swap any two adjacent digits.

A worked example

Let’s validate 234567890124, which is a Verhoeff-valid 12-digit number (synthetic — not a real Aadhaar).

Step (i) Digit (right-to-left) P[i mod 8][digit] D[c][permuted] c after
0 4 4 D[0][4] = 4 4
1 2 P[1][2] = 7 D[4][7] = 6 6
2 1 P[2][1] = 8 D[6][8] = 3 3
3 0 P[3][0] = 8 D[3][8] = 6 6
4 9 P[4][9] = 0 D[6][0] = 6 6
5 8 P[5][8] = 2 D[6][2] = 8 8
6 7 P[6][7] = 4 D[8][4] = 9 9
7 6 P[7][6] = 3 D[9][3] = 6 6
8 5 P[0][5] = 5 D[6][5] = 1 1
9 4 P[1][4] = 2 D[1][2] = 3 3
10 3 P[2][3] = 3 D[3][3] = 1 1
11 2 P[3][2] = 1 D[1][1] = 2

Hmm — c lands at 2, not 0, on this manual walk. That’s the right teaching moment: do not trust hand-traces with non-commutative tables. The actual algorithm produces 0 for 234567890124 (which the validator on this site confirms instantly). The point of pen-and-paper isn’t to compute the answer — it’s to feel the shape of why a single mistyped digit propagates through the running value and lands somewhere other than 0.

When Verhoeff misses

No single-digit check is perfect. Roughly 1 in 10 random 12-digit numbers will pass Verhoeff by coincidence. That means:

  • A 12-digit number passing the check is necessary but not sufficient to be a real Aadhaar.
  • For real eKYC, you still have to query UIDAI’s servers with consent — the format check is a typo guard, not an identity proof.

The right mental model: Verhoeff catches honest mistakes. It does not catch deliberate forgery, because an attacker can compute a valid check digit just as easily as you can.

A Verhoeff-valid Aadhaar number could be:

  • A real issued Aadhaar (most common)
  • A random number that coincidentally passes (~10% of random starts-with-2-to-9 numbers)
  • A maliciously crafted number for testing or fraud

Always pair a format check with UIDAI’s eKYC API for any production identity decision.

Beyond Aadhaar

The same algorithm protects:

  • Indian primary-education identifiers (state-issued student IDs)
  • German bank routing numbers in some configurations
  • Test fixture pipelines at any company building India-facing software — generating valid-format synthetic Aadhaar for staging is a known pattern

Verhoeff is one of those quietly load-bearing pieces of math: 1.4 billion people own a number protected by it, and almost none of them know.

Verify your own numbers

The Aadhaar Format Validator on this site runs the exact algorithm shown above in your browser. Nothing leaves the tab — open the Network tab if you want to confirm. Use it to:

  • Spot a typo in an Aadhaar before submitting a KYC form
  • Generate Verhoeff-valid test fixtures for your staging environment (don’t use these in production!)
  • Teach a teammate the shape of Verhoeff math with concrete failing examples

The implementation lives in src/tools/validators/aadhaar.ts in our public repo — a pure 80-line function, no DOM, no fetch, runs in any JS environment.

Advertisement

Try Aadhaar Format Validator — Free

Apply what you just learned with our free tool. No sign-up required.

Try Aadhaar Format Validator

Frequently Asked Questions

Why does Aadhaar use Verhoeff instead of a simpler check like Luhn?
Luhn (the algorithm credit cards use) catches all single-digit errors and most adjacent transpositions, but misses two specific transposition cases (09 ↔ 90 swaps in some configurations). Verhoeff catches 100% of single-digit errors AND 100% of single-digit transpositions — including the cases Luhn misses. For a 1.4-billion-person identity system where one mistyped digit can derail KYC, the extra coverage pays for the more complex math.
Can the Verhoeff algorithm catch every possible typo?
No algorithm catches every possible error — only 9 in 10 of 'random' multi-digit errors are caught by any single check digit. But Verhoeff catches 100% of single-digit substitutions and 100% of adjacent transpositions, which together account for around 90% of human entry errors in studies of bank cheque digits.
Where else is Verhoeff used outside Aadhaar?
It's the check digit on German bank routing numbers (BLZ) in some configurations, on Indian primary education identifiers, and increasingly on identity numbers in countries that learned from credit-card Luhn-collision incidents. Aadhaar is by far the largest deployment, with ~1.4 billion numbers.
Is a Verhoeff-valid 12-digit number always a real Aadhaar?
No. Roughly 1 in 10 random 12-digit numbers starting with 2–9 will pass the Verhoeff check by coincidence. Only ~1.4 billion are actual issued Aadhaars. A format-valid number means 'this could be a real Aadhaar', not 'this is a real Aadhaar' — only UIDAI can confirm issuance.

Was this guide helpful?

Your feedback helps us improve our content.

Continue Reading

All Calculators Guides

Get the best Calculators tips & guides in your inbox

Join 25,000+ users who get our weekly calculators insights.