How do you check if a card number is valid?
Card numbers end in a check digit calculated with the Luhn algorithm, so you can verify a number's internal consistency without contacting anyone. This tool strips spaces and dashes, runs the Luhn check on the 12 to 19 remaining digits, and, if it passes, names the likely network from the number's prefix. It catches typos, not fraud.
The Luhn formula (also called "mod 10") is specified for card numbers in ISO/IEC 7812-1, the standard for issuer identification numbers and primary account numbers. It was designed to catch the mistakes people make when typing or reading out numbers.
The Luhn check, step by step
- Starting from the rightmost digit (the check digit) and moving left, double every second digit.
- If doubling gives a two-digit number, subtract 9 (the same as adding its two digits).
- Add up all the digits, doubled and undoubled.
- The number is valid if the total is a multiple of 10.
Take 4111 1111 1111 1111. Counting from the right, the doubled positions are the 2nd, 4th and so on up to the 16th, which is the leading 4.
| Digits | Count | Treatment | Contribution |
|---|---|---|---|
| Undoubled 1s (positions 1, 3, ... 15) | 8 | added as-is | 8 |
| Doubled 1s (positions 2, 4, ... 14) | 7 | 1 x 2 = 2 | 14 |
| Leading 4 (position 16) | 1 | 4 x 2 = 8 | 8 |
| Total | 30 |
Thirty ends in zero, so the number passes and the tool reports Valid card number (Visa). Change the last digit to 2 and the total becomes 31: the tool answers Invalid card number: fails the Luhn checksum.
Working backwards gives the check digit: for the first fifteen digits 411111111111111, the only final digit that brings the total to a multiple of 10 is 1.
What Luhn catches and what it misses
We ran the tool's own check over thousands of random valid 16-digit numbers. Every single-digit error was caught, as were all swaps of two neighbouring digits except one pair: swapping 09 and 90 leaves the sum unchanged. Single wrong digits and swapped neighbours are exactly the slips that happen when a number is typed or read aloud, which is what the formula was built for.
What it can't do matters more:
- It can't tell you a card exists. About one in ten random digit strings passes. Anyone can generate valid-looking numbers.
- It doesn't check expiry date, CVV or cardholder name. Those aren't part of the number.
- It doesn't contact a bank or card network. Whether a card is active or has funds is only known to the issuer.
If you're building a checkout, use a Luhn check to give instant feedback on typos, then let your payment provider do the real verification.
How the network is detected
After a number passes, the tool matches its leading digits and length against these patterns, which follow the issuer identification number (IIN) table in Wikipedia's payment card number article and the network documentation it cites:
| Network | Leading digits the tool checks | Length |
|---|---|---|
| Visa | 4 | 13, 16 or 19 |
| Mastercard | 51 to 55, and 2221 to 2720 | 16 |
| American Express | 34, 37 | 15 |
| Discover | 6011, 644 to 649, 65 | 16 to 19 |
| JCB | 3528 to 3589 | 16 to 19 |
| Diners Club | 30, 36, 38, 39 | 14 to 19 |
Mastercard's 2-series range (2221 to 2720) has been issued since 2017, so a 16-digit number such as 2223 0031 2200 3222 is labelled Mastercard. A number starting with 35 outside 3528 to 3589 isn't a JCB number and shows as unknown card type.
This is a convenience label, not an authoritative lookup. Prefix ranges are assigned and reassigned over time, and co-branded cards can sit inside another network's range: China UnionPay numbers that start with 62 aren't detected, and US and Canadian Diners Club cards starting with 54 or 55 are labelled Mastercard, which is how they're processed. The validity verdict comes only from the Luhn check, so a missing or surprising network name never changes it.
Messages you might see
| Message | Meaning |
|---|---|
Valid card number (Visa). |
Luhn check passed; prefix matched a known pattern |
Valid card number (unknown card type). |
Luhn check passed; prefix not in the table above |
Invalid card number: fails the Luhn checksum. |
Digits are inconsistent, usually a typo |
Enter a card number (12-19 digits, spaces and dashes allowed). |
Too short, too long, or contains other characters |
Privacy
The validator is a small piece of JavaScript that runs on this page. We checked the code: it calls no network APIs, and the page doesn't send the field's contents anywhere. Still, there's rarely a reason to paste a real card number into any website, so use published test numbers when you're testing forms.
Related tools
For other error-detecting codes, the CRC32 calculator shows how checksums protect files and network data. If you're writing your own input validation, try patterns in the regex tester and see the JavaScript lessons for the language this check is written in. For billing paperwork after a payment, there's an invoice generator.
Last updated