Security5 min readUpdated October 15, 2026

What Is the Luhn Algorithm?

Luhn algorithm (mod 10) explained: the steps, a digit-by-digit check of Stripe's 4242 test card, what it catches, what it misses, and a JavaScript check.

Article summary

TL;DR

The Luhn algorithm is a mod 10 checksum that validates card numbers and other IDs. Starting from the right, you double every second digit, subtract 9 from any result above 9, and add everything up. If the total ends in 0, the number is well formed. It catches typos, not fraud.

  • The last digit of a card number is the check digit. The issuer picks it so the whole number passes the mod 10 test.
  • Luhn catches every single-digit typo and almost every swap of two neighboring digits. It misses 09 written as 90.
  • Passing Luhn proves nothing about the card: one random number in ten passes, and card testers only use Luhn-valid numbers.
  • The method is set out in ISO/IEC 7812-1, Annex B, and reused for phone IMEI numbers.
Want to go further? AskChatGPTClaudePerplexityGrok
On this page

What is the Luhn algorithm?

The Luhn algorithm, also called the mod 10 or modulus 10 algorithm, is a check digit formula. The last digit of a card number is a control digit, chosen so the whole number passes a simple sum test. A typo almost always breaks the test, so the form can ask the customer to fix the number before any payment is sent.

Hans Peter Luhn, an IBM engineer, filed the patent on January 6, 1954. US Patent 2,950,048, granted on August 23, 1960, describes a hand-held "computer for verifying numbers" aimed at a common copying error: "transposing two of the digits."2US Patent 2,950,048, Computer for verifying numbers, H. P. Luhn, filed January 6, 1954, granted August 23, 1960 (read October 14, 2026)

The method is set out in Annex B of ISO/IEC 7812, the standard that numbers payment cards; the mobile standards that reuse it point to that exact annex.3ETSI TS 123 003 V17.9.0 (3GPP TS 23.003), clause 6.2.1 and Annex B (read October 14, 2026) The check digit comes after the issuer prefix and the account number: see bank identification number for the other digits.

How the Luhn algorithm works

  1. Start from the right. The last digit is the check digit. Keep it as it is.
  2. Double every second digit moving left: the 2nd, 4th, 6th digit from the right, and so on.
  3. Subtract 9 from any doubled value above 9. 7 doubled is 14, which becomes 5. This is the same as adding the two digits: 1 + 4 = 5.
  4. Add all the digits, doubled and untouched.
  5. Check the total. If it ends in 0 (divides by 10), the number passes. If not, it has an error.

Validating a full card number, check digit included. Remove spaces and dashes first.

Worked example: Stripe's 4242 4242 4242 4242 test card

Stripe documents 4242 4242 4242 4242 as its basic Visa test card.1Stripe Docs, Testing (read October 14, 2026) Counting from the right, the 2s sit in the odd positions (kept) and the 4s in the even positions (doubled).

Positions from the rightDigitStepValue counted
1 (check digit), 3, 5, 7, 9, 11, 13, 152Kept8 digits × 2 = 16
2, 4, 6, 8, 10, 12, 14, 164Doubled: 4 × 2 = 88 digits × 8 = 64
All 16 digitsAdded up16 + 64 = 80

Left to right, 4 2 4 2 ... 4 2 becomes 8 2 8 2 ... 8 2. Each "8 2" pair adds up to 10, and eight pairs make 80, which ends in 0: the number passes. No doubled value goes above 9, so step 3 never applies.

Now change only the last digit: 4242 4242 4242 4241. The total drops to 79, and the number fails. Stripe uses that exact number to simulate an incorrect_number error in tests.1Stripe Docs, Testing (read October 14, 2026)

Generating vs validating the check digit

The same arithmetic runs in two directions:

Generating (issuer)Validating (checkout)
InputThe first 15 digits: 424242424242424All 16 digits
Which digits are doubledThe rightmost digit of the input, then every second oneThe second digit from the right, then every second one
Sum8 × 8 + 7 × 2 = 7880
ResultCheck digit = 80 − 78 = 280 ends in 0: valid

The check digit brings the sum up to the next multiple of 10 (0 if it already ends in 0). Since exactly one digit in ten works, a random 16-digit number passes about one time in ten.

Inside Tagada

See every payment's route, processor by processor

Set the order your processors are tried in, per store, per country or per product.

See how routing works

What Luhn catches and what it misses

ErrorExampleCaught?
One wrong digit4242 ... 4241 instead of ...4242Always
Two neighbors swapped...4224 instead of ...4242 (sum 78)Almost always
09 swapped with 90...09... instead of ...90...Never: both pairs add up to 9
Twin digits changed22 ↔ 55, 33 ↔ 66, 44 ↔ 77Never: the sums stay equal
A made-up number with a correct check digitAny Luhn-valid stringNever

Check the 09 gap by hand: 0 doubled is 0, and 9 doubled is 18, which becomes 9. Either way the pair counts for 9.

Luhn is not a security check

The formula is public, so passing it proves only that the digits are consistent. Stripe's generic decline test card, 4000 0000 0000 0002, passes Luhn and is still declined.1Stripe Docs, Testing (read October 14, 2026) Closed, expired or empty real cards pass too.

BIN attacks generate Luhn-valid numbers from a known issuer prefix, since invalid ones would die in the form. Stripe describes card testers using scripts "to test a large amount of card information at once" and recommends CAPTCHA, rate limits and velocity rules.4Stripe Docs, Protect yourself from card testing (read October 14, 2026) Luhn stops typos; fraud scoring and the issuer's authorization handle fraud. Full playbook: ecommerce fraud prevention.

Other uses: IMEI numbers

A phone's IMEI is 14 digits plus a Luhn check digit. The 3GPP specification says it "is intended to avoid manual transmission errors, e.g. when customers register stolen MEs at the operator's customer care desk," and computes it with the method of ISO/IEC 7812, Annex B.3ETSI TS 123 003 V17.9.0 (3GPP TS 23.003), clause 6.2.1 and Annex B (read October 14, 2026) Some national ID numbers use Luhn or a variant: check each scheme's official rules before reusing a card validator.

Luhn check in JavaScript

An illustrative 10-line version. In production, use the validation built into your payment provider's card field.

function luhnCheck(cardNumber) {
  const digits = cardNumber.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;
}
// luhnCheck("4242424242424242") === true

How Tagada helps

Fraud checks after the format check

A Luhn-valid number can still be a tested or stolen card. TagadaPay runs native 3DS2, device intelligence and a rules engine in the checkout, so each payment can be screened before authorization. Tagada follows Visa and Mastercard rules and the laws that apply to payments.

Nick Bonnassies

CMO at Tagada

CMO at Tagada. Before Tagada, Nick built direct-to-consumer brands that generated over $115M in sales, raised over $25M in crowdfunding and sold two of them. He also works as a fractional CMO on marketing operations and AI systems.

Frequently asked questions

What is the Luhn algorithm used for?

It checks that an identification number was typed or copied correctly. Card numbers are the best-known use: checkout forms run it before sending a payment. Mobile phone IMEI numbers use the same check digit, and some national ID numbers use it or a variant.

Why is it called the mod 10 algorithm?

Because the last step is a modulo 10 test: the weighted sum of the digits must divide evenly by 10, so it ends in 0. Mod 10, modulus 10 and Luhn formula all name the same check.

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

No. It only means the digits are consistent with each other. For any 15 digits, exactly one of the ten possible last digits makes the number pass, so anyone can build valid-looking numbers. Only the issuer's authorization tells you the card exists and can pay.

How do I calculate the check digit?

Take the number without its last digit. Starting from the rightmost digit, double every second digit, subtract 9 from results above 9, and add all the digits. The check digit is the amount needed to reach the next multiple of 10, or 0 if the sum already ends in 0.

Who invented the Luhn algorithm?

Hans Peter Luhn, an IBM engineer. His patent for a hand-held "computer for verifying numbers" was filed on January 6, 1954 and granted on August 23, 1960 as US Patent 2,950,048. It is free to use.

Sources

Checked October 15, 2026
  1. Stripe Docs, Testing (read October 14, 2026)
  2. US Patent 2,950,048, Computer for verifying numbers, H. P. Luhn, filed January 6, 1954, granted August 23, 1960 (read October 14, 2026)
  3. ETSI TS 123 003 V17.9.0 (3GPP TS 23.003), clause 6.2.1 and Annex B (read October 14, 2026)
  4. Stripe Docs, Protect yourself from card testing (read October 14, 2026)

TagadaPay

Screen every card payment before authorization

Tell us what you sell and how you sell it. Each application is underwritten, and approval is not guaranteed.

  1. 01Tell us what you sell and how
  2. 02Underwriting reviews your business
  3. 03Process through TagadaPay alongside your other processors