What is a check digit?

A check digit is an extra digit (or character) appended to the data, calculated from all the other digits using a fixed formula. When a scanner reads the barcode it recomputes the formula and compares - if the recomputed value doesn't match the stored check digit, the read is rejected.

Check digits catch the everyday errors that happen when humans key in numbers and when scanners misread bars: a single digit flipped, two adjacent digits transposed, an entire digit dropped. They do not recover data that has been lost - for that you need a richer scheme like the Reed-Solomon error correction used in QR Code, Data Matrix, and Aztec.

GS1 mod-10 - the GTIN family

Every GTIN (and therefore every EAN-13 , EAN-8 , UPC-A , ITF-14 , and any GS1-128 carrying an AI (01)) uses the same check-digit algorithm. It's the most-used check digit on Earth.

  1. Start from the rightmost data digit (the one just to the left of where the check digit will go).
  2. Multiply alternating digits by 3 and 1, beginning with weight 3 on the rightmost data digit.
  3. Sum all the products.
  4. The check digit is the value that, when added to that sum, brings the total to a multiple of 10. Formula: check = (10 − (sum mod 10)) mod 10

Worked example - EAN-13 590123456789?

Position (from right)DigitWeightProduct
19327
2818
37321
4616
55315
6414
7339
8212
9133
10010
119327
12515
Sum127
Check digit(10 − 7) mod 10 = 3

The full EAN-13 is therefore 5901234567893. The same algorithm works on every GS1 number length - pad the input with leading zeros to GTIN-14 and the computed check digit is identical.

Code 39 / LOGMARS mod-43

Code 39 supports an optional check character; for the US Department of Defense LOGMARS profile it is mandatory. The algorithm uses the standard 43-character Code 39 alphabet:

0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - . space $ / + %
  1. Look up each data character's position in the 43-character table above (0-indexed).
  2. Sum the positions.
  3. Take that sum modulo 43.
  4. The check character is the character at that position in the table.

Worked example for CODE39: C=12, O=24, D=13, E=14, 3=3, 9=9. Sum = 75. 75 mod 43 = 32. Table[32] = W. The full LOGMARS payload is CODE39W.

Code 128 mod-103

Code 128 (and therefore GS1-128) carries a mandatory check character that is computed using a different formula - one that weights characters by their position rather than alternating 3/1:

  1. Each character in Code 128 has a numeric value 0–103.
  2. Multiply the start character's value by 1, then each subsequent data character's value by its 1-indexed position (1, 2, 3, …).
  3. Sum the products, then take modulo 103.
  4. The result is the numeric value of the check character (which has its own Code 128 module pattern).

The check character is silent - it is not visible in the human-readable text printed under the barcode. Most encoder libraries compute it automatically; you almost never need to compute one by hand outside of debugging.

What check digits do - and don't - catch

Catches
  • Any single-digit substitution (every time)
  • Most adjacent-digit transpositions (around 89% for GS1 mod-10)
  • Most single-digit drops or extra digits - the length is wrong, so the formula fails immediately
Doesn't catch
  • Transpositions whose products happen to swap (e.g. 09 → 90 with weights 1 and 3 changes the sum by 18, divisible by 10? No - but other specific transpositions can cancel out)
  • Multi-digit errors that happen to land on the same modulo - rare in practice but possible
  • Damaged bars / missing modules - the symbol stops decoding entirely; that's the scanner's job, not the check digit's

For applications that need to recover from damage rather than just detect it, use a 2D symbology with Reed-Solomon error correction (QR, Data Matrix, Aztec, PDF417) or layer a CRC on top of the encoded payload.

Key standards

Related