The one-sentence version
Replace an integer with its remainder and compute: the result is the same as "compute first, then take the remainder". This holds because the reduction map is a ring homomorphism. Casting out nines, barcodes, bank card numbers, the last digit of an ID number and IBANs all work the same way: add a "fingerprint" to the data, so that a copying error will most likely change it. Any error whose difference falls in the homomorphism's kernel leaves the fingerprint unchanged, and so goes undetected.
This article has three layers:
- The intuition: casting out nines, casting out elevens, and the errors they can and can't catch
- Real-world use: ISBNs, EAN/UPC barcodes, bank card Luhn, ID numbers and IBANs, with brief extensions to CRC and Verhoeff
- The mathematics: , ring homomorphisms, kernels and why "modulo a prime" catches more, with a worked example for each method
About the numbers in the examples
Every book number, card number, ID number and account number in this article is a public test number, an example from a standards document, or a made-up number, and doesn't correspond to any real person. All examples were checked with Python.
Layer 1: The Intuition
1.1 Casting out nines: checking arithmetic with "digit sums"
In primary school you compute and get . How can you quickly check it?
Casting out nines goes like this:
- Add up the digits of each number, repeating until one digit remains (you can also throw away any along the way, which is what "casting out nines" means):
- : ,
- : ,
- Do the same operation on these two "representatives": ,
- Compute the digit sum of the answer: for , ,
- Both sides are , so it passes the check.
Addition and subtraction work the same way:
- . The left side is , and the right side is , . They agree.
- . The left side is , and the right side is , which is after casting out nines. They agree.
Why can a digit sum represent a number? Because "the sum of the digits" and the original number have the same remainder when divided by . For example remainder , exactly the digit sum . The reason is that leaves remainder when divided by , so also leave remainder , and each digit contributes to the remainder only by "its own size". Layer 3 makes this rigorous.
And "remainders" have a nice property: compute then reduce equals reduce then compute. So if the true answer leaves remainder when divided by but yours leaves , your answer must be wrong.
1.2 What casting out nines can and can't catch
Passing the check doesn't mean it's right
Casting out nines can only prove "wrong", never "right". Mismatched remainders mean there is definitely an error; matching remainders only mean it may be right.
What it catches: most single-digit mistakes. For example, writing as changes the digit sum to , which shows up at once.
What it misses:
| Error type | Example | Why it's missed |
|---|---|---|
| Two digits swapped | written as | Same digits, same digit sum |
| written as or vice versa | written as | The digit sum changes by exactly , the same after casting out |
| A digit off by a multiple of | written as ( too many) | The difference is a multiple of |
| An extra or missing | written as | A trailing doesn't change the digit sum |
To sum up: whenever the difference between the wrong and right answers is a multiple of , casting out nines can't see it. "Swapping" in the first row is the most common slip, and it falls exactly in this class: swapping adjacent digits gives a difference of .
1.3 Casting out elevens: using "alternating sums" to fill the gaps
Using the remainder modulo instead fixes the swap problem. Because leaves remainder modulo (that is, remainder ),
The remainder of a number modulo the alternating sum, starting from the units digit, adding then subtracting
For example:
- :
- :
- , and leaves remainder modulo
- : , which agrees ✓
Now look at the two errors casting out nines just missed:
- The swap error : alternating sum , caught
- The -too-many error : remainder modulo , caught too
But casting out elevens has blind spots as well: it can't catch errors whose difference is a multiple of , such as swapping two digits one position apart (both have the same sign, so the alternating sum is unchanged). So in practice the two are often used together. An error slips past both checks only if its difference is a multiple of both and , that is, a multiple of .
1.4 From "checking arithmetic" to "checking numbers"
Check digits use this idea in reverse. Casting out nines checks "the result of a computation"; check digits check "a number being copied or typed":
- Define a "fingerprint function", such as "a weighted sum, reduced modulo "
- When issuing a number, add one digit (the check digit) so that the whole number's fingerprint equals some fixed value, such as
- When someone copies or scans the number, recompute the fingerprint. If it is wrong, the number is wrong
The two most common errors in human copying are:
- Single-digit errors: , about – of manual input errors
- Adjacent swaps: , about –
Designing a check digit means choosing the "modulus" and "weights" so that all of these two classes are caught. Below we look at how each scheme does on these two points.
Layer 2: Real-World Use
First a summary table, with each row explained afterwards:
| Scheme | Modulus | Weights / rule | Single-digit errors | Adjacent swaps |
|---|---|---|---|---|
| Casting out nines | All | Misses | Misses all | |
| ISBN-10 | Catches all | Catches all | ||
| ISBN-13 / EAN / UPC | Alternating | Catches all | Misses pairs differing by (like ) | |
| Luhn (bank cards) | Every other digit "doubled, then digit sum" | Catches all | Misses only | |
| Chinese ID, ISO 7064 MOD 11-2 | Catches all | Catches all | ||
| IBAN, ISO 7064 MOD 97-10 | Catches all | Catches all | ||
| Verhoeff | Dihedral group | Permutations | Catches all | Catches all |
The pattern is obvious: schemes with a prime modulus (, ) do best. Layer 3 explains why.
2.1 ISBN-10: modulo , where the check digit can be X
Book numbers before 2007 had digits , with the rule
Because there are remainders modulo , from to , the check digit sometimes has to equal , which is written as the Roman numeral X. That is why some older books have numbers ending in X.
Example: ISBN 0-306-40615-2 (an example commonly used by Wikipedia and other sources)
| Digit | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Weight | ||||||||||
| Product |
The total is ✓
An example with X: 0-8044-2957-X. The weighted sum of the first digits is , and . The check digit must satisfy , so , written X.
Error detection: all single-digit errors and all swaps (not just adjacent ones) are caught.
- Writing the 8th digit as : the total becomes , caught
- Writing
40615as46015(swapping and ): the total is , caught
2.2 ISBN-13, EAN-13, UPC: modulo , weights and
Supermarket barcodes and today's book numbers use this scheme. Reading left to right, the weights alternate :
(The -digit UPC-A has weights from the left, on the same principle.)
Example: ISBN-13 978-0-306-40615-7
| Digit | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Weight | |||||||||||||
| Product |
The total is ✓. The UPC example 036000291452 passes the same way.
Error detection:
- Single-digit errors: all caught, because multiplying by or never turns a nonzero difference into a multiple of .
- Adjacent swaps: swapping changes the total by . When , the change is , and it can't be caught.
- Example: writing
40615as40165(swapping and ) gives978-0-306-40165-7, which still passes. - The missed pairs are , , , and .
- Example: writing
To stay compatible with barcode systems, ISBN-13 gave up ISBN-10's modulus , so its error detection actually got weaker.
2.3 Bank card numbers: the Luhn algorithm
The last digit of Visa, Mastercard, UnionPay and other card numbers is a Luhn check digit (proposed by Hans Peter Luhn of IBM in 1954). The rule:
- From right to left, multiply the th digits by
- If the result has two digits, add them (equivalent to subtracting ), for example
- Add all the digits; the total must be
Example: 4111 1111 1111 1111 (Visa's public test card number, commonly used in payment development, not a real card)
From right to left, the even positions (positions from the left) are doubled:
- The leftmost is in a doubled position:
- The other doubled positions are all : , totaling
- The undoubled s: totaling
The total is ✓
If you mistakenly write the second-to-last digit as (...1121), this digit is doubled and becomes . The total becomes , and it is caught.
Error detection:
- Single-digit errors: all caught, because "double and take the digit sum" maps one-to-one to , a permutation
- Adjacent swaps: only one kind is missed, . For example, the made-up numbers
4090 0000 0000 0003and4900 0000 0000 0003, both pass Luhn - For why only this pair is missed, see section 3.6 in Layer 3
Luhn isn't a security measure
A check digit only guards against slips, not forgery. The algorithm is public and anyone can compute a valid check digit, so real security comes from the card networks' databases, CVVs and 3-D Secure.
2.4 Digit 18 of the Chinese resident ID: ISO 7064 MOD 11-2
In the -digit ID number , the first digits are a region code, the next are the date of birth, the next are a sequence code, and the last, , is the check digit. The rule is
where is written as X if it needs to equal . This is why some people's ID numbers end in X, for exactly the same reason as ISBN-10.
Reducing modulo , the weights of the first digits are
and the last digit has weight . In practice, first compute the weighted sum of the first digits, then look it up:
| Check digit | X |
(This table is the result of solving .)
Example: 11010519491231002X. This is the example number from the national standard GB 11643—1999, and doesn't correspond to a real person.
| Digit | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Weight | |||||||||||||||||
| Product |
, so , and the table gives check digit X ✓. Verification: ✓.
If the birthday 1231 is copied as 1213 (swapping the adjacent ), the computed check digit becomes , which doesn't match X, and it is caught.
Error detection: all single-digit errors and all adjacent swaps are caught.
2.5 IBAN: modulo
International bank account numbers (IBANs, used in Europe, the Middle East and elsewhere) have two check digits, under the rule ISO 7064 MOD 97-10:
- Move the first characters (the country code and two check digits) to the end
- Replace letters with two-digit numbers:
- The resulting large integer must be
Example: GB82 WEST 1234 5698 7654 32. This is a fictional example account commonly used in IBAN standards documents.
- Move:
WEST12345698765432GB82 - Replace letters ():
- To compute by hand, work in segments: take a segment, reduce it, attach the remainder to the front of the following digits, and reduce again:
This segmented method also works because reduction is a ring homomorphism, as Layer 3 explains.
To generate the check digits, first compute with the check digits set to 00; the check digits are then . In this example the result is exactly .
Why : is the largest prime below . Two check digits can represent at most values, uses nearly all of them, and being prime it detects the most errors. IBAN catches all single-character errors and all adjacent digit swaps, with an actual miss rate of about .
2.6 Extensions: CRC and Verhoeff
CRC (cyclic redundancy check): replacing "modulo a number" with "modulo a polynomial"
Ethernet frames, ZIP archives and PNG images all use CRC. It treats a bit string as the polynomial in (), and takes the remainder modulo a fixed generator polynomial : This is also a ring homomorphism, with kernel the ideal . An error is caught as long as the error polynomial isn't divisible by . A good choice of (such as the degree- polynomial of CRC-32) guarantees catching all consecutive errors (burst errors) of length . This is the same pattern as casting out nines, with replaced by .
The Verhoeff algorithm: solving both error classes at once with the non-commutative group
The schemes above all compute weighted sums in the commutative ring . With a modulus of , some errors are always missed: EAN misses pairs, Luhn misses . It can be proved that a "weighted sum" in can't catch all single errors and all adjacent swaps at once.
Jacobus Verhoeff's 1969 approach: map the digits to the elements of the dihedral group (the symmetries of a regular pentagon: rotations plus reflections), together with a carefully designed permutation . The rule is where is multiplication in (not commutative). Because , swapping adjacent digits generally changes the product, so a single decimal check digit is enough to catch all single errors and adjacent swaps.
Example: the Verhoeff check digit of the string 236 is . 2363 passes the check, while changing it to 2633 fails. India's Aadhaar identity number uses this algorithm.
Layer 3: The Mathematics
3.1 Congruence and
Fix a positive integer . If , we say . This is an equivalence relation, and the equivalence class of is written
All the classes form , with operations defined by
Well-definedness
We need the operations above not to depend on the choice of representatives: if and , then because is an ideal: it is closed under addition and absorbs multiplication (). This is exactly why a quotient ring can define multiplication.
3.2 The reduction map is a ring homomorphism
Define
The operations defined in 3.1 give directly
so is a (surjective) ring homomorphism. In words, "compute then reduce reduce then compute", that is,
Casting out nines is the case : to check , just check whether holds in . has only elements, so very little computation is needed.
Mind the direction of the logic:
but the converse fails. So casting out nines can only refute, never confirm.
The example from 1.1 in the language of homomorphisms
, , , . The two sides are equal, so the homomorphism doesn't refute the equation.
The segmented reduction for IBANs is also an application of the homomorphism property. Let . Then
so you can first replace with its remainder and then reduce , and the result is unchanged.
3.3 Why "" gives the digit sum
Let , where are the digits. With the homomorphism ,
because , so . In other words,
The same goes modulo , because . This is why "a number is divisible by if its digit sum is".
Modulo : , so , and then
which is the alternating sum.
By hand
, where : Indeed ✓
3.4 The kernel is : which errors go undetected
Let the correct answer be , the written answer , and the error . Then
So an error goes undetected if and only if it falls in the kernel. This is the most basic property of a homomorphism: . By the first isomorphism theorem, , and differences in the kernel are completely invisible in the image.
Going through the table in 1.2:
- Single-digit errors: digit changes from to , with error . Because , .
- Adjacent swaps: digits and are . After swapping, the error is so they are never caught.
- Modulo : the same adjacent swap gives . Because is prime, , and when , so and it is always caught.
- Swaps one position apart: , which lies in both and , so neither method catches it.
3.5 The general framework for weighted check digits, and why primes matter
Every "weighted sum" check digit can be written as
is a module homomorphism (linear map) from to , so the analysis is the same as in 3.4: an error vector goes undetected if and only if .
(1) Single-digit errors: digit changes from to , and changes by .
(2) Swapping digits : if they were , the change is
Because digits satisfy , when we have .
Theorem (error detection modulo a prime)
Let be prime with (for example or ).
- If every weight , then all single-digit errors are caught.
- If , then all swaps of digits are caught.
Proof: is prime, so is a field and has no zero divisors: or . Since , , so , that is, is invertible.
- (1) and are both invertible, so the product .
- (2) and are both invertible, so the product .
Checking each in turn:
- ISBN-10 (, ): are all nonzero; for any , is also nonzero. So single errors and swaps at any positions are caught. A check digit of must be written as X, the price of using the prime rather than .
- Chinese ID MOD 11-2 (, ): is invertible in , so every . The weight difference of adjacent digits is so adjacent swaps are all caught. Moreover, is a primitive root modulo , and run through exactly , so any two digits whose distance isn't a multiple of have different weights, and their swaps are caught as well.
- IBAN MOD 97-10 (, by decimal digit, ): is invertible; the adjacent difference is invertible. has order in , so the weights are all different over a very long stretch.
Counterexamples: when the modulus isn't prime, zero divisors cause misses
- EAN (, weights ):
- Single errors: is invertible in (), so all are caught.
- Adjacent swaps: the change is . But is a zero divisor in : . So when the change is , and it isn't caught. This is exactly why changing
40615to40165in 2.2 still passes:
- Casting out nines (, all weights ): for adjacent swaps , so no swap is ever caught.
In one sentence
The point of check digit design is to make the weights and the weight differences all units (invertible elements) in . When is prime, is a field and every nonzero element is a unit, so this is easy. When there are zero divisors and , which always leave holes.
3.6 Why Luhn misses only
Luhn isn't a pure weighted sum. Let the "double and take digit sum" function be
with this table of values:
(Note that , because a digit sum doesn't change the remainder modulo ; 3.3 is at work again.)
Single errors: in an undoubled position, the change is ; in a doubled position, the change is . The table shows is a permutation (injective) of , so when , and both lie between and , so their difference can't be a multiple of . Therefore all single errors are caught.
Adjacent swaps: of two adjacent digits, exactly one is doubled. Say the doubled digit was and the plain one ; after swapping, the doubled digit is and the plain one . The total changes by
Computing :
In , has only one "collision": . So when ,
that is, Luhn misses only the adjacent swap . Intuitively, doubled is still , and doubled is ; both are fixed points of , so the total is the same whichever digit is doubled.
By hand: the test card number
Number the positions from right to left, doubling even : for a total of ✓. A counterexample (made-up numbers): and both pass, because .
3.7 The big picture
How it maps to abstract algebra
| Algebra concept | Role in this article |
|---|---|
| Ring homomorphism | "Reduce then compute compute then reduce", the basis of casting out nines |
| Kernel is an ideal | The undetected errors are exactly those falling in the kernel |
| Well-definedness of the quotient ring | Segmented reduction, digit sums and alternating sums all work |
| is a field ( prime) | Nonzero elements are invertible with no zero divisors, so ISBN-10, Chinese ID and IBAN catch everything |
| Zero divisors () | EAN misses swaps with difference |
| Polynomial quotient ring | CRC |
| Non-commutative group | The Verhoeff check |