Luhn Algorithm Validator

Validate and generate Luhn check digits (mod 10 algorithm) for credit cards, IMEI, ICCID, and other identifier numbers. Everything runs in your browser — numbers are never transmitted.

Card / Identifier Number

Result

Enter a number above to validate

How the Luhn Algorithm Works

  1. Starting from the rightmost digit (the check digit), move left.
  2. Double the value of every second digit. If doubling results in a number greater than 9, sum the digits (e.g., 7×2=14 → 1+4=5).
  3. Sum all the digits (both doubled and untouched).
  4. If the total mod 10 = 0, the number is valid.

Where Luhn Is Used

IdentifierTypical LengthCheck Digit
Credit / Debit Card (PAN)13–19 digitsLast digit
IMEI (mobile device ID)15 digitsLast digit
ICCID (SIM card serial)19–20 digitsLast digit
NPI (US healthcare provider)10 digitsLast digit
Canadian SIN9 digitsLast digit
Privacy note: All validation runs in your browser using JavaScript. No card numbers are ever sent to a server. Test numbers provided are industry-standard test PANs — not real cards.

Related Tools

CRC Calculator | Crypto Checksum Verifier | EMV TLV Parser | Luhn Algorithm Guide | Credit Card Validation Guide | Luhn Tool Comparison

Real-World Luhn Applications

The Luhn algorithm is used in many identification number systems worldwide. Understanding where and how it is applied helps in developing payment systems, SIM card management tools, and device identity verification.

Credit Card Structure

Credit card numbers (PAN) follow ISO/IEC 7816 and are typically 16 digits. The structure: 6-digit BIN/IIN (Bank Identification Number) identifying the issuer, variable-length account number, and a single Luhn check digit at the end. The BIN range determines the card brand: 4=Visa, 51-55 and 2221-2720=Mastercard, 34/37=Amex, 6011/65=Discover, 62=UnionPay. This tool automatically detects the brand from the BIN and validates the Luhn check digit.

IMEI and ICCID

IMEI (International Mobile Equipment Identity) is a 15-digit number identifying a mobile device. The first 8 digits are the TAC (Type Allocation Code) identifying the model, followed by a 6-digit serial number and a Luhn check digit. The first 2 digits of TAC typically indicate the manufacturer. ICCID (Integrated Circuit Card Identifier) is a 19-20 digit number identifying a SIM card, starting with 89 (telecommunications industry identifier), followed by country code and issuer ID. Both use Luhn for the check digit. For TLV-encoded card data, use our BER-TLV Parser.

What Luhn Can and Cannot Detect

Luhn is a single-digit error detector — nothing more. Understanding its coverage prevents a dangerous over-reliance on a passing check.

Error TypeExampleDetected?
Single-digit typo4532…0366 → 4532…0866Yes, always
Adjacent transposition…1283 → …1823Yes, almost always
Twin transposition (non-adjacent)4…9…4 → 9…4…4Mostly — some pairs slip through
Double-digit typotwo independent wrong digits~50% slip through
Completely random number10-digit guess~10% pass by luck

The last row is the critical one for testers: a random 16-digit number has a roughly 1-in-10 chance of being Luhn-valid. That's why Luhn validation is a sanity filter, not fraud detection — payment systems pair it with BIN range checks, length rules, and issuer verification. Generating test data? A Luhn-valid number is trivially constructible (our Generate tab does it), which is exactly why the algorithm protects against typos and transcription errors, and exactly why it provides zero security against fabrication.

Luhn Variants You May Encounter

Several industries extended or adapted the mod-10 scheme, and knowing the variant prevents false "invalid" verdicts:

When a known-good number fails plain Luhn, check whether the issuer uses one of these variants before declaring the data corrupt — GSM SIMs, for example, sometimes carry provider-specific check conventions in the issuer extension digits.

Luhn Test Vectors Worth Bookmarking

A handful of canonical test values make debugging any Luhn implementation painless — keep these in your unit tests:

NumberValid?What it proves
79927398713YesThe classic worked example from the algorithm's literature; sum is exactly 70
4532015112830366YesVisa-shaped 16-digit; if this fails, your right-to-left doubling is broken
4532015112830367NoSingle-digit mutation of the above; must be rejected
5500005555555559YesMastercard-shaped edge case where a doubled 9 yields 18 → 9
0NoGuards against empty/single-digit inputs sneaking through as "valid"

If your implementation disagrees with any row above, the most common culprit is doubling in the wrong direction — Luhn always doubles every second digit starting from the rightmost, which means the check digit itself (position 1) is never doubled.

Implementing Luhn in Your Own Code

The algorithm is small enough to inline anywhere. Reference implementations, right-to-left with the doubling pattern described above:

// JavaScript
function luhnValid(num) {
  const d = num.replace(/\D/g, '');
  let sum = 0, alt = false;
  for (let i = d.length - 1; i >= 0; i--) {
    let n = +d[i];
    if (alt) { n *= 2; if (n > 9) n -= 9; }
    sum += n; alt = !alt;
  }
  return d.length >= 2 && sum % 10 === 0;
}
# Python
def luhn_valid(num: str) -> bool:
    d = [int(c) for c in num if c.isdigit()]
    if len(d) < 2: return False
    total = 0
    for i, n in enumerate(reversed(d)):
        if i % 2 == 1:
            n *= 2
            if n > 9: n -= 9
        total += n
    return total % 10 == 0

Common implementation bugs: doubling the wrong parity of digits (start doubling from the second-from-right, not the leftmost), forgetting the n > 9 → subtract 9 fold, and failing to strip spaces/dashes before parsing. Test against the standard vector 4532015112830366 (valid) and 4532015112830367 (invalid) before shipping.