Finance

How the Luhn Algorithm Validates a Credit Card Number

7 min read

Every credit card number carries a built-in checksum called the Luhn algorithm. Double every second digit from the right, adjust any result over 9, add everything up, and the total must land on a multiple of 10. If it doesn’t, the card number is malformed, and that gets caught before the number ever reaches a bank.

The rule

Starting from the rightmost digit and moving left, double every second digit. If doubling produces a two-digit number, subtract 9 from it (that’s the same as adding its two digits together, so 16 becomes 1+6=7). Leave the untouched digits as they are. Add all sixteen results together. If the sum is divisible by 10, the number passes the check.

That’s the entire algorithm. It runs in your browser, in a point-of-sale terminal, or in a payment form’s client-side validation, with no network call required.

Worked example: checking a real card number step by step

Take the number most developers have seen in a Stripe or PayPal sandbox: 4111 1111 1111 1111. It’s a public Visa test number, not a real customer card, and safe to use in examples.

Number the digits from the right, position 1 through 16. Even positions get doubled:

Position (from right)16151413121110987654321
Digit4111111111111111
Doubled?yesnoyesnoyesnoyesnoyesnoyesnoyesnoyesno
Contribution8121212121212121

Position 16 is even, so the leading 4 is doubled: 4 x 2 = 8, and since 8 is a single digit, no adjustment is needed. The seven other doubled positions all hold a 1, and 1 x 2 = 2 for each of them, so those seven contribute 14 in total (7 x 2). The eight untouched positions are all 1, contributing 8.

Add it up: 14 (from the doubled 1s) + 8 (from the leading 4) + 8 (from the untouched digits) = 30.

30 is a multiple of 10, so the number passes. That matches reality: 4111111111111111 is a genuine, widely published Visa test number.

Why a single typo fails the check

Change just the last digit, from 1 to 2, so the number reads 4111 1111 1111 1111 with the final digit as 2: 4111111111111112. That last digit sits at position 1, which is never doubled, so it contributes its face value directly to the sum.

The original sum was 30, built partly from that final digit contributing 1. Swap it to 2 and the sum becomes 31.

31 is not divisible by 10. The check fails immediately, on the client, before the number is ever sent to a payment processor. That’s the entire point of Luhn: it’s a fast, offline sanity check that filters out fat-finger typos and garbled scans before they cost a network round trip.

Common test numbers by network

Every major card network publishes Luhn-valid test numbers for developers to use in sandbox environments. These are safe to publish and appear in official Stripe and PayPal documentation.

NetworkTest numberDigits
Visa4111 1111 1111 111116
Visa (alternate)4012 8888 8888 188116
Mastercard5555 5555 5555 444416
American Express3782 822463 1000515
Discover6011 1111 1111 111716

Notice American Express breaks the usual 4-4-4-4 grouping: it’s a 15-digit number grouped 4-6-5, which trips up validators that assume every card is 16 digits.

Try it with your own number

Paste any of the numbers above, or a number of your own, into the checker below. It runs the Luhn algorithm live, detects the network from the prefix, and shows the formatted number as you type.

Card network -
Luhn checksum -

What Luhn does NOT tell you

A Luhn pass only means the number is arithmetically well-formed. It says nothing about whether the card exists, whether it’s active, whether it has been reported stolen, or whether it has any funds behind it. You can construct plenty of Luhn-valid numbers that were never issued to anyone.

Confirming a card is real, live and chargeable requires an actual authorization request to the issuing bank through a payment processor, which is a completely separate step from this checksum. Luhn is the first, cheapest filter in the pipeline, not the last one.

Common mistakes and edge cases

The most common real-world failure is a checkout form that runs Luhn on a string still containing spaces or dashes. Strip everything but digits before checksumming, or every valid card typed with grouping will fail.

The second is assuming every card number is 16 digits. American Express is 15, some Diners Club numbers are 14, and UnionPay ranges from 16 to 19. Length alone isn’t a validity signal, and Luhn doesn’t care about length at all, it works on however many digits you feed it.

The third is more interesting: Luhn has a known blind spot. If two adjacent digits are transposed and their difference is exactly 9, meaning a 0 and a 9 sitting next to each other get swapped, the checksum comes out identical and the error slips through undetected. This is a documented, well-understood limitation of the algorithm, not a flaw in any particular implementation. It’s rare in practice (you need a 0 and a 9 adjacent to begin with) but worth knowing if you’re relying on Luhn as your only input-quality gate.

Frequently asked questions

Does a Luhn-valid number mean the card is real?

No. Luhn only checks that the digits are internally consistent, the way a checksum on a barcode confirms it was scanned correctly. Whether the card was actually issued, is active and has available funds can only be confirmed by the issuing bank during an authorization request.

Why do doubled digits over 9 get reduced by subtracting 9?

Doubling a digit from 5 to 9 always stays under 10, but doubling 5 through 9 produces a two-digit result (10 through 18). Luhn’s rule is to sum the two digits of that result, and subtracting 9 is a shortcut for exactly that: for any number n from 10 to 18, the sum of its digits equals n - 9. So 8 x 2 = 16, and 1 + 6 = 7, which is the same as 16 - 9.

Can I use the same test numbers to test my own checkout form?

Yes, that’s what they’re published for. Stripe, PayPal and most payment gateways document these same numbers (or close variants) for sandbox testing, and none of them belong to a real cardholder. If your form rejects 4111 1111 1111 1111 in test mode, the bug is almost always in your form’s parsing or length check, not in the card number itself.

Is Luhn the same thing as card verification (CVV)?

No, they check completely different things. Luhn validates the primary account number itself, a purely mathematical property of the digits. The CVV is a separate 3 or 4-digit security code printed on the card, used to prove the person submitting a transaction has physical possession of the card. A number can be Luhn-valid and still fail on a wrong or missing CVV.

Credit Card Number Validator
Now try it yourself with the full tool.
Try it now