Check Digit Calculator & Bulk GTIN Validator
Every retail barcode number — EAN-13, UPC-A, EAN-8, ITF-14 — ends in a check digit computed from the digits before it. This page computes it, verifies it, and shows the mod-10 arithmetic step by step. And where GS1's own calculator takes one number at a time, the bulk validator below takes a whole column pasted from Excel: up to 500 numbers per pass, each verified or completed, with a corrected column you can copy straight back.
Single number — compute or verify
Runs locally in your browser — nothing you type is transmitted or stored.
Bulk validator — paste a column
Paste up to 500 numbers, one per line — straight from an Excel or Sheets column. Validated locally; your list never leaves the browser.
Companion guide: Bulk GTIN validation modes follows a pasted column through both readings — numbers with their check digit, or data digits waiting for one — status by status, up to the 500-row cap. See also how GTIN check digits are computed and all guides.
How the mod-10 check digit works
Take the data digits — everything except the final digit — and weight them alternately by 1 and 3, anchored at the right: the digit immediately before the check digit always gets weight 3. Multiply, sum the products, and the check digit is whatever brings that sum up to the next multiple of ten. That single algorithm, from the GS1 General Specifications, protects the whole GTIN family regardless of length.
Worked example — data digits 400638133393: the weighted products sum to
89; the next multiple of ten is 90; so the check digit
is 90 − 89 = 1.
Complete EAN-13: 4006381333931
These figures are computed at build time by the same tested engine the calculator above runs in your browser, so the prose cannot drift from the code.
The check digit can be 0, and that is not a placeholder: the fictional data digits
100000000003 sum to 10, already a multiple of ten, so there is nothing
to add and the engine appends 0. The worked-math line under the
calculator says so rather than printing an empty subtraction.
Verify or compute: the length decides, and the verdict says which
The single-number tool never asks what you meant: it strips spaces and hyphens, counts the digits, and states how it read them. Eight, twelve, thirteen, and fourteen digits are complete numbers — GTIN-8, -12, -13, -14 — and the final digit is verified against the rest. Seven and eleven digits have no complete-number reading, so the check digit is computed and appended, and the verdict says so rather than passing the result off as validation.
Twelve and thirteen digits are genuinely ambiguous, and the engine's rule is stated rather
than hidden: the complete-number reading wins, because validating is this page's job. The
cited data digits 400638133393 — twelve digits with no check digit yet — are read as a
complete GTIN-12, and the note reads "Check digit should be 0, not 3." The tool then names the road not
taken: read as data digits, the completed GTIN-13 would be 4006381333931. The
bulk validator makes the same choice an explicit switch, and the
validation-modes guide follows a column through
both.
How to read the verdict
The result box prints the reading in a fixed shape. A verified number opens with its family and "check digit … is correct". A failed verification opens with the family and "wrong check digit", names the expected and supplied digits, and puts the corrected number on its own line; the input is left as typed. A completed number opens with the check digit and the complete number, then says how many data digits it read. A second reading, when one exists, begins "Meant as data digits without a check digit?" A line no reading can use never reaches the verdict: the engine's sentence appears as the field error under the input.
What a mismatch tells you — and what a pass does not
A mismatch is always real: the digits supplied cannot all be right, and it usually means one
of the other digits is wrong. Change the seventh data digit of 4006381333931 from
1 to 7 and the number becomes 4006387333931;
the engine reports "Check digit should be 5, not 1." — expected 5, supplied
1 — and stops there. The corrected number sits in its own field, never written
over the input: overwriting the last digit would turn a detectable mistake into a plausible wrong
number.
A pass is weaker. Swapping two adjacent digits a and b changes the weighted sum by 2(a − b), a
multiple of ten exactly when the digits are equal or differ by five. In 4006381333931
the fifth and sixth data digits are 3 and 8; swap them and
4006831333931 still verifies — the sum moves from 89 to
79 and the required digit stays 1. That is the
whole content of "structurally valid": consistent with each other, not with the number you
meant. The EAN-13 page works a caught swap beside this escaped one.
Leading zeros and the right-anchored weights
The weights are anchored at the right-hand end, not counted from the left, and a leading zero
shows why. A zero multiplies to nothing, and every other digit keeps its distance from the
right, so no weight moves: the cited UPC-A data digits 03600029145 sum to
58 and take check digit 2; as the twelve EAN-13 data digits
003600029145 they sum to 58 and take 2. The
property tests behind this engine pin exactly that. It is also why the leftmost weight is
1 for twelve data digits but
3 for eleven and
3 for thirteen.
One algorithm, every packaging level
A product's 13-digit barcode number rarely travels alone. The same
item is a GTIN-13 on the shelf unit (EAN-13), a GTIN-12 in North
America (UPC-A), and becomes a GTIN-14 on the shipping case (ITF-14): an indicator digit 1–8 is prefixed to the data digits and the check digit is recomputed
with the identical mod-10 arithmetic — only right-aligned over one more digit. Our example
4006381333931 at case level with indicator 1 becomes 14006381333938: the products now
sum to 92, so the final digit changes from 1 to
8. That is why a carton code never shares its parent's check digit by
accident, and why the bulk validator handles all four lengths — 8, 12, 13, and 14 digits —
with one algorithm.
A correct check digit is not a licensed number
Passing the math means the digits are structurally valid — internally consistent, nothing more. Any invented 13-digit string whose last digit happens to satisfy the sum will pass this and every other check-digit calculator, including GS1's. Whether a number is a licensed, registered GTIN that stores and marketplaces will accept is decided by GS1's registry, not by arithmetic. If you are deciding whether you need officially licensed numbers at all, start with do I need a GS1 barcode? — the honest answer depends on where you sell.
How the bulk validator reads your column
Each non-blank line is trimmed and cleaned of spaces and hyphens, then read by digit count. In the default mode — numbers include their check digit — 8-, 12-, 13-, and 14-digit lines are complete numbers and are verified; 7- and 11-digit lines have no complete reading, so their check digit is computed and appended and the row is labeled completed, not valid. In data only mode every line is data digits: 7, 11, 12, and 13 digits become a GTIN-8, -12, -13, or -14, and any other count is not usable.
A column of 11 lines — the cited EAN-13, UPC-A, EAN-8, and GS1 GTIN-14 the engine is tested against, the corrupted EAN-13 from above, the same EAN-13 pasted with spaces, two data-only lines, a blank line, a ten-digit fragment, and a lettered line — run through the same engine at build time in the default mode:
| Input | Read as | Status | Complete number | Note |
|---|---|---|---|---|
4006381333931
|
GTIN-13 | Check digit correct | 4006381333931 |
Check digit 1 is correct. |
4006387333931
|
GTIN-13 | Wrong check digit | 4006387333935 |
Check digit should be 5, not 1. |
400 6381 33393 1
|
GTIN-13 | Check digit correct | 4006381333931 |
Check digit 1 is correct. |
036000291452
|
GTIN-12 | Check digit correct | 036000291452 |
Check digit 2 is correct. |
73513537
|
GTIN-8 | Check digit correct | 73513537 |
Check digit 7 is correct. |
7351353
|
GTIN-8 | Check digit appended | 73513537 |
Check digit 7 appended. |
400638133393
|
GTIN-12 | Wrong check digit | 400638133390 |
Check digit should be 0, not 3. |
09506000134352
|
GTIN-14 | Check digit correct | 09506000134352 |
Check digit 2 is correct. |
5901234123
|
— | Not usable | — | 10 digits — not a GTIN length. Complete numbers have 8, 12, 13, or 14 digits; 7- and 11-digit lines get their check digit appended. |
ABC-123
|
— | Not usable | — | Contains characters other than digits, spaces, and hyphens. |
The summary line reads 10 numbers checked: 5 valid ·
2 wrong check digit · 1 completed ·
2 not usable; the blank line was skipped, so 10
non-blank lines produced 10 rows. Switch the column to data only and the readings
change, not the arithmetic: 6 completed,
4 not usable, nothing verified. 400638133393 flips from a wrong
GTIN-12 to the completed GTIN-13 4006381333931; the GTIN-14 and the EAN-8 are
refused — "14 digits — data digits without a check digit come as 7, 11, 12, or 13." — and the corrupted 4006387333931 is simply extended
to 40063873339316. Data-only mode cannot catch a wrong check digit, because it
never looks for one.
The cap is an engine constant, not a guess about your browser: 500 rows. Fed
503 copies of 4006381333931, the report returns 500
rows and the summary adds "Only the first 500 of 503 non-blank lines
were processed." Nothing beyond the cap is validated, and nothing is dropped silently.
In the table, Read as names the family the line was taken for, or a dash when none exists; Status is one of four labels, with Wrong check digit set in bold because that row needs a decision; Complete number is what the corrected column carries, blank for a row that is not usable; Note is the engine's own sentence. Copy corrected column writes those numbers one per line in the original order and reports how many rows were left blank.
One more misreading: the cited UPC-A 036000291452 without its leading zero,
36000291452, is eleven digits and has only the data-only reading —
"Check digit 2 appended." and 360002914522, a structurally valid GTIN-12 that is
not the number you started with. Check digit appended, not Check digit correct, is the
warning: nothing was verified.
What this page does not check
The scope is one algorithm. ISBN-10 check characters use mod-11 with X standing for ten and belong to the ISBN barcode tool, which also performs the 978 conversion and refuses the reverse for 979. Code 128 carries its symbol check inside the bars, and this site's Code 39 omits the optional mod-43 check, a deliberate omission the methodology page lists; both are covered in the code-set guide. Nothing here looks at bars: whether a printed symbol scans is a matter of contrast, size, substrate, and quiet zones — see what a decoder can certify.
Check digit FAQ
I pasted 12-digit numbers expecting a 13th digit — why do some rows say "wrong check digit"?
A 12-digit line is ambiguous: a complete UPC-A (11 data digits plus a check digit) or the first 12 digits of an EAN-13 still waiting for its check digit. By default the validator reads it as a complete number. If your column has no check digits yet, switch to "Data only — append the check digit" and every line gets its digit computed and appended.
If the check digit is correct, is the barcode number valid?
It is structurally valid: the digits are internally consistent under the GS1 mod-10 algorithm, and that is all a check digit can tell you. Whether the number is a licensed, registered GTIN is a matter of GS1 records, not arithmetic — any 13-digit string with a matching final digit passes the math.
How many numbers can I validate at once?
Up to 500 per pass, entirely in your browser. Longer lists are cut off openly — the summary says only the first 500 lines were processed. For bigger files, paste in batches.
Is my product list uploaded anywhere?
No. Parsing, validation, and the check-digit math run as JavaScript on your device. Nothing you type or paste is transmitted, logged, or stored; closing the page discards it.
Why is the check digit sometimes 0 — is that a placeholder?
No. The check digit is whatever lifts the weighted sum to the next multiple of ten; when the sum already sits on one there is nothing to add. The fictional data digits 100000000003 sum to 10, so the engine appends 0 and the worked-math line says the sum is already a multiple of ten.
Which lines come back as "Not usable", and why?
Two kinds. Lines that still contain anything other than digits once spaces and hyphens are stripped — the note reads "Contains characters other than digits, spaces, and hyphens." And lines whose digit count has no reading in the chosen mode — a ten-digit line in data-only mode reports "10 digits — data digits without a check digit come as 7, 11, 12, or 13." No number is invented for these rows; they stay blank in the corrected column.
If the check digit is correct, will the printed barcode scan?
Not necessarily — this page checks math, not optics. A correct check digit means the digits are internally consistent. Whether a printed symbol scans depends on contrast, size, substrate, and preserved quiet zones, none of which arithmetic can see — read a physical sample with your own scanner before production.
Scope, honestly: this page verifies arithmetic — digits and their mod-10 consistency. It cannot tell you whether a number is registered to a company, and it does not check ISBN mod-11 checks (the ISBN barcode tool does). Everything runs locally in your browser; see the methodology page for how the verification layer is tested.