A Luhn verification test passes when a number's digits, processed with the mod-10 formula, produce a total divisible by 10. The procedure: starting from the rightmost digit and moving left, double every second digit, subtract 9 from any result above 9, then add all the digits together. If the total ends in 0, the number is consistent with the Luhn checksum. If it ends in anything else, at least one digit is wrong or transposed. That is the whole test, and it runs in a single pass over the string with no lookup tables and no external data. The criteria that matter when you evaluate or build a verifier are correctness on edge cases, handling of non-digit input, treatment of leading zeros, and whether the tool is honest about what a pass actually means.

Luhn Algorithm Validation Test

Step-by-step procedure

  1. Strip spaces, hyphens, and any other separators so you have a bare digit string.
  2. Reject the input if it contains anything other than the digits 0 through 9, or if the length is shorter than two characters.
  3. Starting at the rightmost digit, count positions 1, 2, 3 and so on moving left.
  4. For every digit in an even position, double it. If the doubled value is 10 or more, subtract 9 (equivalently, add the two digits of the product).
  5. Leave digits in odd positions unchanged.
  6. Sum every value.
  7. The number passes if the sum modulo 10 equals 0.

When you are generating a check digit rather than verifying one, run the same pass over the payload digits with the positions shifted by one, then choose the final digit that brings the total up to the next multiple of 10.

Test Luhn Number Generator: How to Validate CVV Numbers

Worked example: 79927398713

Reading right to left, the digits in even positions are 1, 8, 3, 2, and 9. Doubling gives 2, 16, 6, 4, and 18. Reducing the two-digit results gives 2, 7, 6, 4, and 9, which sum to 28. The untouched digits in odd positions are 3, 7, 9, 7, 9, and 7, which sum to 42. The grand total is 70, and 70 modulo 10 is 0, so the number passes. Change the final 3 to a 0 and the total becomes 67, which fails. Swap two adjacent digits anywhere in a passing number and the total usually shifts by a nonzero amount, which is why the algorithm catches most single-digit errors and most transpositions.

related article

What the test proves and what it does not

A pass means the digits are internally consistent. It does not mean an account exists, that a card is active, that the number was issued by anyone, or that a transaction will authorize. Random seventeen-digit strings pass roughly one time in ten, so a pass rate near 10 percent on generated input is expected and tells you nothing about validity. Luhn also cannot detect the transposition of 09 and 90, and it cannot detect a doubled error that happens to cancel out. Any workflow that treats a Luhn pass as proof of a live account is built on a false premise.

Luhn Algorithm Check Test: A Comprehensive Guide for Online CVV Verification

Criteria for a reliable verifier

  • Accepts only ASCII digits and rejects Unicode digit characters that look identical on screen.
  • Preserves leading zeros instead of coercing the input to an integer, which silently drops them and shifts every position.
  • Documents whether separators are stripped before or after length validation.
  • Returns a clear pass or fail value rather than a percentage or a pseudo-confidence score.
  • States plainly that the check is a format test, not a validity or authorization test.

Test vectors for your implementation

  • 79927398713: pass, the standard worked example.
  • 79927398710: fail, final digit altered.
  • 4111111111111111: pass, a widely published test number.
  • 4532015112830366: pass, another published test value.
  • 0000000000000000: pass, all zeros satisfy the checksum, which is a good reminder that the test is arithmetic only.
  • 7992739871: pass when treated as a payload whose check digit is being computed, not verified.

Where Luhn is used outside payments

The formula appears far beyond card numbers. IMEI device identifiers use it for the final check digit, as do National Provider Identifiers in US healthcare, Canadian Social Insurance Numbers, and several national identity and account numbering schemes. The same seven steps apply in each case, which is why a correct implementation is worth writing once and testing against known vectors. Payment card numbering itself is governed by ISO/IEC 7812, which specifies the check digit calculation as part of the issuer identification number structure.

Common implementation mistakes

Three bugs account for most failing test suites. The first is starting the doubling pass at the wrong end, which happens when a developer counts from the left and forgets that the parity flips depending on string length. The second is applying the subtract-9 rule to every digit instead of only to doubled values above 9. The third is treating the input as a number, which strips leading zeros and can also lose precision on long identifiers. Add an odd-length case and an even-length case to your unit tests, and each of these surfaces immediately.