Luhn Algorithm: Checker, Calculator and Explanation
The Luhn algorithm, also called mod 10, is the checksum that validates credit card numbers. Starting from the rightmost digit, double every second digit, subtract 9 from any result above 9, and add all the digits together. The number is valid if the total is a multiple of 10.
Luhn checker, step by step
| Digit | 4 | 2 | 4 | 2 | 4 | 2 | 4 | 2 | 4 | 2 | 4 | 2 | 4 | 2 | 4 | 2 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Doubled? | Γ2 | β | Γ2 | β | Γ2 | β | Γ2 | β | Γ2 | β | Γ2 | β | Γ2 | β | Γ2 | β |
| Value | 8 | 2 | 8 | 2 | 8 | 2 | 8 | 2 | 8 | 2 | 8 | 2 | 8 | 2 | 8 | 2 |
Sum = 80. It is a multiple of 10, so the number passes the Luhn check.
Luhn check digit calculator
Enter every digit except the last one and get the check digit that makes the number valid.
Check digit: 2 β full number4242424242424242
How the Luhn algorithm works
- Start from the rightmost digit, the check digit, and move left.
- Double every second digit: the second from the right, the fourth, the sixth, and so on.
- If doubling gives a two-digit number, subtract 9 from it. For example, 7 doubled is 14, which becomes 5. This is the same as adding the two digits, 1 + 4.
- Add up all the digits: the doubled ones after step 3 and the ones you left alone.
- If the total ends in 0, meaning it is divisible by 10, the number is valid.
Worked example: 4242 4242 4242 4242
Reading from the right, the digits alternate 2, 4, 2, 4 and so on. Every 4 is in a doubled position and becomes 8, while every 2 stays as it is. That gives eight 8s and eight 2s: 64 + 16 = 80. Since 80 is a multiple of 10, the number passes. It is Stripe's standard test card.
Calculating the check digit
To create a valid number, apply the same steps to the number without its last digit, remembering that the doubling now starts with its rightmost digit. Take the total modulo 10; the check digit is 10 minus that remainder, or 0 if the remainder is already 0. Every number from the card generator ends in a check digit calculated this way.
What it catches, and what it does not
Luhn catches every single-digit mistake and almost every swap of two neighbouring digits. The exception is 09 written as 90, or the reverse. It misses some "twin" errors, such as 22 typed as 55, and any change that happens to keep the total the same.
It is an error check, not a security feature. Anyone can produce a number that passes it, so a valid Luhn result says nothing about whether a card exists or has funds. Besides payment cards, the same checksum protects IMEI numbers on mobile phones and Canadian Social Insurance Numbers. It is named after Hans Peter Luhn, the IBM scientist who patented it in 1960.
Luhn algorithm in code
Luhn algorithm in JavaScript
function isValidLuhn(number) {
const digits = number.replace(/\D/g, '');
let sum = 0;
let double = false;
for (let i = digits.length - 1; i >= 0; i--) {
let d = Number(digits[i]);
if (double) {
d *= 2;
if (d > 9) d -= 9;
}
sum += d;
double = !double;
}
return digits.length > 0 && sum % 10 === 0;
}
isValidLuhn('4242 4242 4242 4242'); // trueLuhn algorithm in Python
def is_valid_luhn(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
is_valid_luhn("4242 4242 4242 4242") # TrueLuhn algorithm in Java
static boolean isValidLuhn(String number) {
String digits = number.replaceAll("\\D", "");
int sum = 0;
boolean doubleIt = false;
for (int i = digits.length() - 1; i >= 0; i--) {
int d = digits.charAt(i) - '0';
if (doubleIt) {
d *= 2;
if (d > 9) d -= 9;
}
sum += d;
doubleIt = !doubleIt;
}
return !digits.isEmpty() && sum % 10 == 0;
}Luhn algorithm in PHP
function isValidLuhn(string $number): bool {
$digits = preg_replace('/\D/', '', $number);
$sum = 0;
$double = false;
for ($i = strlen($digits) - 1; $i >= 0; $i--) {
$d = (int) $digits[$i];
if ($double) {
$d *= 2;
if ($d > 9) $d -= 9;
}
$sum += $d;
$double = !$double;
}
return $digits !== '' && $sum % 10 === 0;
}Luhn algorithm in C#
// using System.Linq;
static bool IsValidLuhn(string number)
{
var digits = new string(number.Where(char.IsDigit).ToArray());
int sum = 0;
bool doubleIt = false;
for (int i = digits.Length - 1; i >= 0; i--)
{
int d = digits[i] - '0';
if (doubleIt)
{
d *= 2;
if (d > 9) d -= 9;
}
sum += d;
doubleIt = !doubleIt;
}
return digits.Length > 0 && sum % 10 == 0;
}Luhn plus format: what makes a card number valid
Every major card network uses the Luhn check digit. A number must also start with one of the network's prefixes and have the right length.
| Network | Starts with | Length |
|---|---|---|
| Visa | 4 | 13, 16 or 19 (almost always 16) |
| Mastercard | 51β55, 2221β2720 | 16 |
| American Express | 34, 37 | 15 |
| Discover | 6011, 644β649, 65 | 16β19 |
| Diners Club | 36, 300β305, 38β39 | 14β19 |
| JCB | 3528β3589 | 16β19 |
| UnionPay | 62 | 16β19 |
| Maestro | 5018, 5020, 5038, 6304, 6759, 6761β6763 | 12β19 |
| RuPay | 60, 65, 81, 82, 508 | 16 |
| Mir | 2200β2204 | 16β19 |
To check prefix, length and checksum in one go, use the credit card validator.
Luhn algorithm FAQ
What is the Luhn algorithm?
A checksum formula used to validate credit card numbers and other identifiers. From the right, every second digit is doubled (subtracting 9 from results over 9), all digits are added, and the number is valid if the total is divisible by 10.
Is the Luhn algorithm the same as mod 10?
Yes. It is also called the modulus 10 or mod 10 algorithm, because the final test is whether the sum leaves a remainder of 0 when divided by 10.
Does passing the Luhn check mean a credit card is real?
No. Luhn only catches typing mistakes. Generating a number that passes is trivial, so a valid result says nothing about whether a card exists, is active or has funds.
What errors does the Luhn algorithm detect?
All single-digit errors and almost all transpositions of adjacent digits, except 09 and 90. It does not catch some twin errors, such as 22 written as 55.
Who invented the Luhn algorithm?
Hans Peter Luhn, a computer scientist at IBM. His patent for it was granted in 1960, and it is now specified in ISO/IEC 7812 for payment card numbers.