The Luhn Algorithm Explained: How Credit Card Numbers Validate Themselves
Ever wonder how a website knows your credit card number is wrong before it even tries to charge you? The secret is a brilliant piece of 1950s mathematics hiding in plain sight on every card in your wallet.
The Magic Number in Your Wallet
Every credit card number contains a tiny mathematical secret: the last digit isn’t random. It’s a check digit calculated from all the other digits using a formula called the Luhn algorithm.
This single digit can catch:
- 🔢 Any single mistyped digit
- 🔄 Most transposed adjacent digits (typing
12instead of21) - ⌨️ Common keyboard mistakes
All without making a single network request.
Try it yourself: Enter any card number in our Luhn Validator to see the algorithm in action.
What is the Luhn Algorithm?
The Luhn algorithm (also known as the mod 10 check, modulus 10 algorithm, or simply the Luhn formula) is a simple checksum formula invented by Hans Peter Luhn, an IBM computer scientist, in 1954.
Originally designed for validating identification numbers, it became the global standard for credit card validation. Today, it’s used by:
- Visa, Mastercard, Amex, Discover — all major card networks
- IMEI numbers — your smartphone’s unique identifier
- Canadian Social Insurance Numbers (SIN)
- National Provider Identifiers (NPI) — US healthcare
- ISIN — International Securities Identification Numbers
The algorithm is public domain, meaning anyone can implement it freely.
Also Known As…
You might hear this algorithm called by different names:
| Name | Context |
|---|---|
| Luhn algorithm | Academic / technical documentation |
| Mod 10 check | Industry shorthand |
| Modulus 10 | Mathematical terminology |
| Luhn formula | General usage |
| Luhn checksum | When referring to the validation result |
They all mean the same thing!
How the Luhn Algorithm Works
The beauty of Luhn is its simplicity. Here’s the complete algorithm in 4 steps:
Step 1: Start from the Right
Begin with the rightmost digit (the check digit) and work your way left.
Step 2: Double Every Second Digit
Starting from the second-to-last digit and moving left, double every other digit.
Card: 4 5 3 9 → Double positions 2 and 4 from right
5 × 2 = 10
4 × 2 = 8
Step 3: Handle the Overflow
If any doubled digit is greater than 9, subtract 9 from it.
10 - 9 = 1 ✓
8 stays 8 ✓
Why subtract 9? It’s the same as adding the two digits of the result (1 + 0 = 1). Subtracting 9 is just faster!
Step 4: Sum and Check
Add up all the digits (modified and unmodified). If the total is a multiple of 10, the number is valid.
Valid: Sum % 10 === 0 ✅
Invalid: Sum % 10 !== 0 ❌
That’s it. Four steps, no complex math, no cryptography.
Worked Example: The Famous Test Card
Let’s validate the classic Visa test number: 4111 1111 1111 1111
The Grid Method
| Position | Digit | Double? | Result | Notes |
|---|---|---|---|---|
| 16 (rightmost) | 1 | No | 1 | Check digit |
| 15 | 1 | Yes | 2 | 1 × 2 = 2 |
| 14 | 1 | No | 1 | |
| 13 | 1 | Yes | 2 | 1 × 2 = 2 |
| 12 | 1 | No | 1 | |
| 11 | 1 | Yes | 2 | 1 × 2 = 2 |
| 10 | 1 | No | 1 | |
| 9 | 1 | Yes | 2 | 1 × 2 = 2 |
| 8 | 1 | No | 1 | |
| 7 | 1 | Yes | 2 | 1 × 2 = 2 |
| 6 | 1 | No | 1 | |
| 5 | 1 | Yes | 2 | 1 × 2 = 2 |
| 4 | 1 | No | 1 | |
| 3 | 1 | Yes | 2 | 1 × 2 = 2 |
| 2 | 1 | No | 1 | |
| 1 (leftmost) | 4 | Yes | 8 | 4 × 2 = 8 |
Sum: 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 8 = 30
30 % 10 = 0 → ✅ VALID!
A More Interesting Example
Try 4532 0150 1234 5678:
| Digit | 4 | 5 | 3 | 2 | 0 | 1 | 5 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Double? | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||||||||
| Result | 8 | 5 | 6 | 2 | 0 | 1 | 1 | 0 | 2 | 2 | 6 | 4 | 1 | 6 | 5 | 8 |
Sum: 8+5+6+2+0+1+1+0+2+2+6+4+1+6+5+8 = 57
57 % 10 = 7 → ❌ INVALID!
Interactive breakdown: Our Luhn Validator shows the digit-by-digit calculation with color-coded boxes.
How the Check Digit Is Calculated
When creating a card number, the issuer:
- Generates the first 15 digits (for a 16-digit card)
- Runs the Luhn algorithm treating the check digit as 0
- Calculates:
(10 - (sum % 10)) % 10 - That’s the check digit!
For example, if the sum is 57, the check digit would be:
(10 - (57 % 10)) % 10 = (10 - 7) % 10 = 3
Card Brand Detection: The BIN Range
The first 6-8 digits of a card number form the Bank Identification Number (BIN), also called the Issuer Identification Number (IIN). This tells you the card network:
| Card Network | Prefix(es) | Length |
|---|---|---|
| Visa | 4 | 13, 16, 19 |
| Mastercard | 51-55, 2221-2720 | 16 |
| American Express | 34, 37 | 15 |
| Discover | 6011, 644-649, 65 | 16-19 |
| JCB | 3528-3589 | 16-19 |
| UnionPay | 62 | 16-19 |
So when you type 4, the form already knows you’re entering a Visa card!
What Luhn Does NOT Protect Against
Here’s the critical part that many developers miss:
❌ NOT a Security Feature
The Luhn algorithm is not cryptographic. It provides:
- No authentication — It doesn’t prove the card is real
- No authorization — It doesn’t check if funds exist
- No fraud prevention — It can’t detect stolen cards
❌ Doesn’t Catch Everything
The algorithm will miss:
| Error Type | Example | Detected? |
|---|---|---|
| Single digit typo | 4111 → 4112 | ✅ Yes |
| Adjacent transposition | 41 → 14 | ✅ Usually |
| Twin errors (09↔90) | 09 → 90 | ❌ No |
| Jump transposition | 4111 → 1141 | ❌ No |
| Multiple errors | Various | ❌ Often missed |
The twin error exception (09 ↔ 90) is a known weakness! Both produce the same Luhn sum.
✅ What It’s Actually For
Luhn is a typo catcher, pure and simple. It saves unnecessary network round-trips by catching accidental mistakes before submission.
JavaScript Implementation
Here’s the same algorithm used in our Luhn Validator:
function luhnCheck(cardNumber) {
// Remove any non-digit characters
const digits = cardNumber.replace(/\D/g, '');
// Must be 13-19 digits for valid card
if (digits.length < 13 || digits.length > 19) {
return false;
}
let sum = 0;
let isEven = false; // Start from right, first position is odd
// Process right to left
for (let i = digits.length - 1; i >= 0; i--) {
let digit = parseInt(digits[i], 10);
if (isEven) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
isEven = !isEven;
}
return sum % 10 === 0;
}
// Test it!
console.log(luhnCheck('4111111111111111')); // true
console.log(luhnCheck('4111111111111112')); // false
100% client-side: Like all our tools, this runs entirely in your browser. No data is ever sent to a server.
Quick Reference: The Algorithm
For those who love a compact summary:
FOR each digit from right to left:
IF position is even (2nd, 4th, 6th...):
digit = digit × 2
IF digit > 9: digit = digit - 9
sum = sum + digit
VALID = (sum mod 10) equals 0
Or as a memory trick:
“Double, subtract nine, sum to a multiple of ten.”
Test Card Numbers
Here are some commonly used test numbers (all pass Luhn validation):
| Network | Test Number | Status |
|---|---|---|
| Visa | 4111 1111 1111 1111 | Always declines |
| Visa | 4012 8888 8888 1881 | Always declines |
| Mastercard | 5555 5555 5555 4444 | Always declines |
| Mastercard | 5105 1051 0510 5100 | Always declines |
| Amex | 3782 822463 10005 | Always declines |
| Discover | 6011 1111 1111 1117 | Always declines |
⚠️ Remember: These pass Luhn validation but will always be declined online. They exist for development testing only.
The History: Hans Peter Luhn
The algorithm is named after Hans Peter Luhn (1896-1964), a German-American computer scientist at IBM. Beyond the checksum formula, Luhn was a prolific inventor who filed over 80 patents and is credited with:
- KWIC indexing — The predecessor to modern search engines
- Key Word in Context — Text retrieval innovation
- Early work on business intelligence — Called it “selective dissemination of information”
The Luhn algorithm was created in 1954 and patented (US Patent 2,950,048), but the patent has long since expired, making it freely usable.
Next Steps
Now that you understand how card numbers validate themselves:
- Try the validator: Luhn Validator & Bitmap Calculator
- Parse complete messages: ISO 8583 Studio (where PANs live in Field 2)
- Explore response codes: Reference Database to see what happens after validation
- Learn about EMV: EMV Field 55 Guide for chip card cryptography
- Understand tokenization: Payment Tokenization Guide — network tokens pass the same Luhn check as real PANs
- Debug declines: Response Codes Guide — code
14(Invalid Card Number) is the Luhn failure in action - Discover the future of payments: Read our FedNow vs. Traditional Card Networks Guide to see how instant payments eliminate card networks.
This post is part of the ISO 8583 Mastery series. Follow along as we explore payment messaging in depth.
Related Posts
💬 Discussion
Have a question or feedback? Leave a comment below — powered by GitHub Discussions.
What is the Luhn Algorithm?
The Luhn Algorithm, or mod 10 algorithm, is a simple checksum formula used to validate identification numbers, most notably credit card numbers and IMEI numbers.
Does the Luhn check prove a credit card is real?
No. The Luhn algorithm only checks for accidental transcription errors (like mistyping a digit). It does not verify whether the card account actually exists, is active, or has sufficient funds.
How does the Luhn algorithm work?
Starting from the rightmost digit, every second digit is doubled. If doubling results in a number greater than 9, the digits of the product are summed. Finally, all digits are added together; if the total modulo 10 equals 0, the number is valid.