Command Palette

Search for a command to run...

Luhn Algorithm: How Credit Card Validation Works

Luhn Algorithm: How Credit Card Validation Works

T
Toolz Team
|Sep 13, 2026|16 Мин. читать

Часть коллекции обеспеченность

Валидатор кредитной карты

Проверьте номер кредитной карты на контрольной сумме Luhn и определите сеть ее карт. Подтверждает только формат, никогда не связывается с банком.

Открыть инструмент «Валидатор кредитной карты»

I build toolz.dev, and before that I spent years shipping WordPress plugins and Laravel APIs, several of which had to take payments. The first checkout form I ever wrote sent every mistyped card number straight to the payment gateway and waited for it to bounce. It worked, technically, but it was slow and it burned through gateway requests on numbers that could never have been valid in the first place. The fix was embarrassingly small: run the Luhn checksum in the browser before submitting. That one change caught most typos instantly and stopped a stream of pointless API calls. This guide is about that check, the prefix rules that sit next to it, and the Credit Card Validator I built so you never have to reimplement either from memory.

TL;DR: A credit card validator confirms that a number is structurally correct, not that it belongs to a real account. It runs two independent tests: the Luhn checksum from ISO/IEC 7812-1, which catches almost every single-digit typo and adjacent transposition, and a length-and-prefix check against each network's published issuer ranges. A number can pass one and fail the other, so the two results are reported separately. It runs entirely in your browser, so no card number is ever uploaded, and it can never tell you whether a card has money on it. Only the issuer knows that.

What does it mean for a card number to be valid?

A payment card number, formally a Primary Account Number or PAN, is not a random string of digits. Its structure is defined by ISO/IEC 7812. The first six to eight digits are the Issuer Identification Number, or IIN, which used to be called the Bank Identification Number (BIN). Those digits identify the network and the issuing bank. The digits after that up to the second-to-last are the individual account identifier, and the very last digit is a check digit computed with the Luhn algorithm.

So "valid" has two separate meanings, and it helps to keep them apart. The first is that the number obeys the Luhn checksum, meaning the check digit is consistent with the rest of the number. The second is that the number has the right length and prefix for a real card network. A number can satisfy one condition and not the other. 4111 1111 1111 1112 has a Visa prefix and a Visa length but fails Luhn. A random sixteen-digit string that happens to end in the right check digit passes Luhn but may start with a prefix no network owns. A good validator tells you which of the two failed, because the fix is different in each case.

What neither check can do is tell you the card is real. Structural validity is about the shape of the number, not the state of the account behind it. The account might not exist, might be frozen, might be over its limit, or might have been closed years ago. The only system that knows is the issuing bank, and it answers exactly once, during an authorization request in a live transaction. Everything a browser-side validator does is a cheap pre-filter that runs before you ever get to that point.

How does the Luhn algorithm work?

The Luhn algorithm, also called the mod-10 algorithm, was patented by Hans Peter Luhn at IBM in 1960 and is now in the public domain. It is a checksum, which means its whole purpose is to detect accidental errors, not to provide any security. It works like this. Starting from the rightmost digit and moving left, you double every second digit. If doubling produces a number greater than nine, you subtract nine from it (which is the same as adding its two digits together). Then you sum all the digits, the doubled ones and the untouched ones. If the total is divisible by ten, the number passes.

Here is the check on 4111 1111 1111 1111, working right to left. The rightmost digit is position one and is not doubled. Doubling every second digit gives a set of ones and twos, the twos coming from the doubled positions. Add them all up and the total lands on a multiple of ten, so the number passes. Change any single digit and the sum almost always stops being a multiple of ten, which is exactly what makes the check useful.

The value of Luhn is in what it catches. It detects every single-digit error, meaning any one digit typed wrong. It also catches almost every transposition of two adjacent digits, the classic "I typed 21 instead of 12" mistake, with one known exception: it does not catch a swap of 09 and 90, because both map to the same weighted sum. That is a genuine blind spot, but it is a rare one, and it is the reason Luhn is a checksum rather than a cryptographic guarantee. For form validation it is more than good enough, and it is why it sits behind the card fields of essentially every checkout on the internet.

How is the card network detected?

The network is read from the leading digits, the IIN. Each network owns specific prefix ranges, and most also restrict the total length. The validator matches the longest, most specific prefix first, because some ranges overlap. Here are the ranges it checks:

Network Starts with Valid lengths Security code
Visa 4 13, 16, 19 3
Mastercard 51-55, 2221-2720 16 3
American Express 34, 37 15 4
Discover 6011, 65, 644-649, 622126-622925 16, 19 3
Diners Club 300-305, 309, 36, 38-39 14, 16, 19 3
JCB 3528-3589 16-19 3
UnionPay 62 16-19 3
Maestro 50, 56-69 (selected) 12-19 3

The overlaps are the interesting part, and getting them wrong is how naive detectors misfire. Mastercard added the 2221-2720 range in 2017, so a detector written before then reports those cards as unknown. Discover owns a narrow slice of the 62 space, 622126 through 622925, while UnionPay owns the rest of 62, so the order you test them in decides whether a 6221 card reads as Discover or UnionPay. The validator tests the specific Discover window before the broad UnionPay prefix so both land correctly. American Express is the one that trips up formatting code, because it uses fifteen digits grouped 4-6-5 rather than the usual four groups of four, and it uses a four-digit security code (the CID printed on the front) rather than the three-digit CVV on the back.

How to use the credit card validator

The tool is deliberately simple. You paste a number and read the result. There is no submit button and nothing to configure.

Step 1: Enter the number

Type or paste the card number into the field. Spaces and dashes are ignored, so 4111-1111-1111-1111, 4111 1111 1111 1111, and 4111111111111111 all validate identically. This matters because real input arrives in every format: copied from a spreadsheet, read off a card, or pulled from a test fixture.

Step 2: Read the verdict

The top of the result tells you plainly whether the number is valid, and if it is not, it names the reason. Underneath, the two checks are shown separately: whether the Luhn checksum passed, and whether the length matches the detected network. Seeing them apart is the point. A number that passes Luhn but fails length almost always means a digit was dropped or added, whereas a number that fails Luhn but has the right length usually means one digit is simply wrong.

Step 3: Check the detected network

The tool shows the network it identified from the prefix, the lengths that network allows, and how long its security code should be. This is useful on its own when you are building a form and want to show the right card logo, or when you need to know whether to expect a three- or four-digit CVV.

Step 4: Copy the formatted or masked number

You can copy the number grouped the way its network prints it, or copy a masked version that hides every digit except the last four. The masked form is the one you want in logs, screenshots, and support tickets, because storing or displaying a full PAN is exactly the kind of thing that gets people in trouble with compliance.

Where does validation fit, and where does it stop?

The honest framing is that a validator is a filter, not a gate. It belongs at the front of a process to reject obvious garbage cheaply, and it must never be trusted as proof of anything downstream. In a checkout form, running Luhn client-side lets you flag a typo the moment the user finishes typing, before they hit pay, which is a better experience and saves a doomed round trip to the gateway. In a data pipeline, validating card-shaped fields catches corrupted rows before they reach a system that will choke on them. In test suites, you need numbers that pass validation so the form behaves the way it will in production, which is what published test numbers are for.

What it does not do is authorize, and this is worth being blunt about. A valid number is not a working card. The tool cannot check a balance, cannot confirm the account exists, and has no connection to any bank. It also cannot, and should not, generate numbers tied to real accounts. The sample numbers it offers are the standard test values published by payment providers, which are Luhn-valid and pass network checks precisely so developers can exercise their forms, but which map to nothing chargeable. If you are building anything that touches real payments, the actual validation of whether a card can be charged happens server-side through your payment processor, and the card data itself should be tokenized so your own systems never store a raw PAN. Client-side validation is the polite front door, not the vault.

How does this compare to validating on the server?

Both have a place, and they answer different questions. Client-side validation with Luhn and prefix checks is instant and private, it gives the user feedback before they submit, and it costs you nothing. Its limit is that it only knows about structure. Server-side validation through a payment processor is the only thing that can confirm a card is real and chargeable, but it costs a network request, it may cost money per authorization attempt, and it happens after the user has committed to submitting. The sensible design uses both: the browser catches the typos and the shape errors for free, and the server does the one check that matters when the user pays. Skipping the client check makes the form feel slow; skipping the server check means you never really validated anything. If you are assembling a broader kit for this kind of work, the developer productivity tools roundup covers the other utilities that tend to live alongside it.

A card validator rarely travels alone. When you are hardening a form or a data pipeline, you are usually also generating identifiers, hashing values, and checking other kinds of input. The hash generator is what you reach for when you need to fingerprint a value rather than validate its shape, and the password strength checker applies the same "measure it in the browser, never send it anywhere" principle to credentials. On the network side, the IP subnet calculator is the companion tool for anyone building the infrastructure a checkout runs on.

For the wider context, the data privacy and online tools guide explains why running sensitive checks client-side matters, and the coding tools guide puts the validator in the context of the rest of a developer's daily kit. Everything on toolz.dev runs in your browser, which is the whole reason a card number is safe to paste into it: it never leaves your device.

Frequently asked questions

What does the Luhn algorithm check?

The Luhn algorithm is a mod-10 checksum that verifies a number was not mistyped. It doubles every second digit from the right, subtracts nine from any result above nine, sums all the digits, and confirms the total is divisible by ten. It catches every single-digit error and almost every swap of two adjacent digits, but it is a checksum, not a security feature, and it cannot prove a card is real.

Does a valid number mean the card works?

No. A valid number only means the digits are structurally correct, so the checksum passes and the length matches the network. Whether the account exists, has a balance, or is still active can only be confirmed by the card issuer during a real authorization. Structural validity is a pre-filter, not proof of a usable card.

How is the card brand detected from the number?

The brand is read from the first digits, the Issuer Identification Number. Visa starts with 4, Mastercard with 51-55 or 2221-2720, American Express with 34 or 37, and so on. Each network also allows only certain total lengths, so the validator checks the prefix and the length together and reports the network it matched.

Is it safe to enter a card number into this tool?

Yes. The number is processed entirely in your browser and is never uploaded, logged, or transmitted. You can confirm this by disconnecting from the internet, because the validator keeps working with no connection. That said, you should still avoid pasting a real card number anywhere you do not need to, and prefer the published test numbers for development.

Why does my real card pass Luhn but fail the length check?

That usually means a digit was dropped or added while typing. The Luhn checksum can pass by coincidence on a number of the wrong length, so the tool checks length independently against the detected network. Re-enter the full number and both checks should pass together.

What are test card numbers and why do they exist?

Test card numbers such as 4111 1111 1111 1111 are published by payment providers so developers can exercise checkout forms. They are Luhn-valid and pass network checks so the form behaves exactly as it will in production, but they map to no real account and can never be charged. They are the correct thing to use anywhere you would otherwise be tempted to type a real card.

What is the difference between the CVV and the card number?

The card number is the long Primary Account Number that identifies the account. The CVV, CVC, or CID is the short security code, three digits for most networks and four for American Express, printed separately from the number. This tool validates the card number only; it does not check the security code, which is verified by the issuer during a transaction.

Can this validator generate working credit cards?

No. It only checks numbers you enter, and it has no way to produce a number tied to a live account. The sample numbers it offers are the standard published test values that reach no real account. Generating numbers for a real card is not something a structural validator can do, and it is not something this tool attempts.


Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!