The Luhn Algorithm Explained: How Credit Card Numbers Validate Themselves

7 min read
ISO 8583 Guides

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 12 instead of 21)
  • ⌨️ 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:

NameContext
Luhn algorithmAcademic / technical documentation
Mod 10 checkIndustry shorthand
Modulus 10Mathematical terminology
Luhn formulaGeneral usage
Luhn checksumWhen 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

PositionDigitDouble?ResultNotes
16 (rightmost)1No1Check digit
151Yes21 × 2 = 2
141No1
131Yes21 × 2 = 2
121No1
111Yes21 × 2 = 2
101No1
91Yes21 × 2 = 2
81No1
71Yes21 × 2 = 2
61No1
51Yes21 × 2 = 2
41No1
31Yes21 × 2 = 2
21No1
1 (leftmost)4Yes84 × 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:

Digit4532015012345678
Double?
Result8562011022641658

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:

  1. Generates the first 15 digits (for a 16-digit card)
  2. Runs the Luhn algorithm treating the check digit as 0
  3. Calculates: (10 - (sum % 10)) % 10
  4. 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 NetworkPrefix(es)Length
Visa413, 16, 19
Mastercard51-55, 2221-272016
American Express34, 3715
Discover6011, 644-649, 6516-19
JCB3528-358916-19
UnionPay6216-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 TypeExampleDetected?
Single digit typo41114112✅ Yes
Adjacent transposition4114✅ Usually
Twin errors (09↔90)0990No
Jump transposition41111141No
Multiple errorsVarious❌ 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):

NetworkTest NumberStatus
Visa4111 1111 1111 1111Always declines
Visa4012 8888 8888 1881Always declines
Mastercard5555 5555 5555 4444Always declines
Mastercard5105 1051 0510 5100Always declines
Amex3782 822463 10005Always declines
Discover6011 1111 1111 1117Always 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:

  1. Try the validator: Luhn Validator & Bitmap Calculator
  2. Parse complete messages: ISO 8583 Studio (where PANs live in Field 2)
  3. Explore response codes: Reference Database to see what happens after validation
  4. Learn about EMV: EMV Field 55 Guide for chip card cryptography
  5. Understand tokenization: Payment Tokenization Guide — network tokens pass the same Luhn check as real PANs
  6. Debug declines: Response Codes Guide — code 14 (Invalid Card Number) is the Luhn failure in action
  7. 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

Debugging Payment Declines: Understanding ISO 8583 Response Codes
Jan 31, 2026 7 min
Understanding ISO 8583 Message Structure
Jan 30, 2026 4 min
Decoding EMV Field 55: A Complete Guide to Chip Card Data
Jan 30, 2026 6 min

💬 Discussion

Have a question or feedback? Leave a comment below — powered by GitHub Discussions.

Frequently Asked Questions

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.

\n