Skip to content
SimpleTools24

The Luhn Algorithm Explained (With a Worked Example)

By SimpleTools24Published 3 min read

The Luhn algorithm (also called the "mod 10" check) is a simple checksum used to catch typing mistakes in card numbers and other identifiers. Starting from the rightmost digit, you double every second digit, subtract 9 from any result over 9, and add everything up. If the total is a multiple of 10, the number passes. The last digit of a card number is a check digit chosen so that the total works out. Passing the Luhn check only means the number is well-formed; it says nothing about whether a real account exists.

Where It Comes From

The algorithm is named after Hans Peter Luhn, an IBM researcher who patented it in the 1950s. It's specified in ISO/IEC 7812 for payment card numbers and is also used for IMEI numbers on mobile phones, some national ID numbers and various account numbers.

How to Check a Number, Step by Step

Take the made-up number 4539 5781 2345 6789.

  1. Starting from the rightmost digit (the check digit, 9), move left and double every second digit.
  2. If doubling gives a number greater than 9, subtract 9 (the same as adding its two digits: 14 → 1 + 4 = 5).
  3. Add all the resulting digits.
  4. If the sum ends in 0, the number is Luhn-valid.
Luhn check for 4539 5781 2345 6789 (doubled digits marked)
Digit4539578123456789
Doubled?yesyesyesyesyesyesyesyes
Value8569177143853779

Sum: 8 + 5 + 6 + 9 + 1 + 7 + 7 + 1 + 4 + 3 + 8 + 5 + 3 + 7 + 7 + 9 = 90. It ends in 0, so the number passes.

How the Check Digit Is Calculated

To create a valid number, you work out the last digit from the others:

  1. Write the number without its check digit: 4539 5781 2345 678.
  2. Treat a placeholder 0 as the check digit and run the steps above. Here the sum is 81.
  3. The check digit is whatever brings the total up to the next multiple of 10: 90 − 81 = 9.

In formula form: check digit = (10 − (sum mod 10)) mod 10.

Code

JavaScript

javascript
function luhnValid(number) {
  const digits = String(number).replace(/\D/g, '');
  let sum = 0;
  for (let i = 0; i < digits.length; i++) {
    let d = Number(digits[digits.length - 1 - i]);
    if (i % 2 === 1) {
      d *= 2;
      if (d > 9) d -= 9;
    }
    sum += d;
  }
  return digits.length > 0 && sum % 10 === 0;
}

luhnValid('4539 5781 2345 6789'); // true

Python

python
def luhn_valid(number: str) -> bool:
    digits = [int(c) for c in number if c.isdigit()]
    total = 0
    for i, d in enumerate(reversed(digits)):
        if i % 2 == 1:
            d *= 2
            if d > 9:
                d -= 9
        total += d
    return bool(digits) and total % 10 == 0

What It Catches, and What It Doesn't

Luhn was designed for accidental errors, not security:

  • Catches: every single-digit typo, and most swaps of two adjacent digits.
  • Misses: some transpositions (notably 09 ↔ 90), and multiple errors that happen to cancel out.
  • Not a security check: anyone can compute a valid check digit. Passing Luhn doesn't mean a card exists, is active or belongs to the person entering it.

That's why payment systems check much more than Luhn, including the issuer's authorisation. Why generated card numbers don't work explains the difference.

Where Luhn Fits in Card Validation

A sensible front-end check combines:

  1. Only digits (after removing spaces).
  2. A length that matches the card network.
  3. A known starting range for the network.
  4. The Luhn check.

Credit card number structure explains the first three. The real decision about a card always comes from the payment processor.

Test Data With Valid Check Digits

When testing a form that runs Luhn validation, you need numbers that pass it but aren't real cards. The test card generator creates synthetic, Luhn-valid numbers for seven networks in your browser, for development and QA only. For end-to-end payment testing, use your payment provider's published sandbox numbers; how to test payment forms covers both.

Frequently Asked Questions

Is the Luhn algorithm the same as mod 10?

Yes. "Mod 10 check" usually refers to Luhn.

Does every card number pass the Luhn check?

Major payment card numbers are designed to, which is why it's a useful typo check.

Can Luhn tell me if a card is real?

No. It only checks the arithmetic of the digits.

Where else is Luhn used?

IMEI numbers, some national identifiers and various account numbers.

Summary

Double every second digit from the right, subtract 9 where needed, add up, and check for a multiple of 10. Luhn is a great typo catcher and nothing more.

Sources