What the Luhn test actually tells you
The Luhn algorithm is a mod-10 checksum. It answers one narrow question: does this string of digits end in the correct check digit? If someone mistypes a single digit, the total shifts and the check fails. If two adjacent digits get swapped, the total usually shifts too. That is the entire job. A number that passes is well formed. A number that fails is wrong, and you know it before the request ever leaves the page.
How the check runs
- Start at the rightmost digit and move left, doubling every second digit.
- If a doubled value comes out to 10 or more, subtract 9 from it. That is the same as adding the two digits of the result together.
- Add every doubled value and every untouched value into one total.
- If the total divides evenly by 10, the number passes.
The canonical worked example is the test vector 79927398713. Doubling alternate digits from the right and reducing anything over 9 gives a sum of 70, so it passes. Change the final 3 to a 4 and the sum becomes 71, so it fails. That is the whole mechanic, and it takes maybe fifteen lines of code in any language.
luhn algorithm validation test
Where the check shows up
- Credit and debit card numbers under ISO/IEC 7812
- IMEI numbers on mobile devices
- Certain national ID and social insurance numbers
- Gift cards, loyalty cards, and some account numbers
Hans Peter Luhn patented the method at IBM in the 1950s as a way to catch keypunch errors. The purpose has not changed since: it is data entry hygiene.
What it cannot do
About one in ten random digit strings passes the check by accident, so passing carries very little weight on its own. The algorithm says nothing about whether an account exists, whether it is open, whether it has funds, or who typed it in. It also misses real errors. Two mistakes can cancel out, and the transposition of 09 into 90 slips through because those digits double to the same reduced values. There is no issuer lookup and no network call here, just arithmetic on a string.
Testing the Luhn Formula: A Guide for Secure CVV Verification
Testing an implementation
Things I look at when reviewing a validator:
- Known good and known bad vectors, including the classic ones from the spec
- Leading zeros, which break the moment someone parses input as an integer
- Non-digit characters, either stripped consistently or rejected outright
- Empty input, single-digit input, and very long input
- Formatted input with spaces or hyphens, so the strip step happens before the math
- Whether the check digit must be present, since a truncated number will just fail
Off by one is the usual bug. Doubling from the left instead of the right flips which positions get doubled, and for odd-length strings the result changes. Test with both odd and even digit counts.
Where it belongs in a checkout flow
The right place is a first-pass filter in a payment form. Catch the typo in the browser, show a plain message, and let the customer fix it before the authorization request goes anywhere. It is not a security control and should not be presented as one. Anyone can compute a check digit with a calculator, so treat this as a way to reduce failed submissions, not a way to verify anything.
One note on scope: I am describing the public checksum used for form validation and for learning how check digits work. It is not evidence that a card is real, and it is not a tool for handling payment data that is not yours.