tooldura

Developer Tools

What a Barcode Actually Stores, and Why Yours Won't Scan

T
tooldura editorial
9 min readUpdated August 31, 2026Open tool →

A scanner does not see bars. It sees a strip of light coming back off a surface, converts that to a waveform, and measures the distance between the points where the signal crosses from light to dark and back. Everything a linear barcode encodes lives in those distances. That single fact explains most of what looks arbitrary about barcodes: why the white margin around the symbol is part of the specification, why a code stretched by one corner handle in a layout tool stops working, and why the answer to "how small can I print this" is a number in millimetres rather than in pixels.

The Number Is in the Widths

Every linear symbology divides its symbol into a grid of equal columns called modules, and the width of one module is the X-dimension. A bar is one or more dark modules in a row, a space is one or more light ones, and a character is a fixed pattern of them.

Code 128 makes this unusually tidy: every character is exactly 11 modules wide, split into three bars and three spaces, and ISO/IEC 15417 lists all 107 of the patterns it uses. Code 39 works differently. Each of its characters is nine elements, three of them wide and six narrow, which is where the name comes from. EAN and UPC give every digit seven modules arranged as two bars and two spaces.

None of this depends on absolute size. A scanner reading a symbol has no idea how large it is or how far away it sits; it works entirely in ratios between the widths it measures. That is why the same artwork scans on a bottle label and on a warehouse sign, and why scaling a barcode is safe as long as both dimensions scale together. Stretch it horizontally only and the ratios still hold, which is why a barcode survives being dragged wider; squash it enough and print artefacts start to matter more than the shape.

Why the Last Digit Is Not Yours

A misread barcode is worse than an unread one. An unread code makes someone scan again; a misread code sells the wrong product at the wrong price and nobody notices. Check digits exist to make the second failure improbable.

The modulo 10 rule GS1 uses across EAN-8, UPC-A, EAN-13 and GTIN-14 is the same in all four: counting from the right-hand end of the data, multiply the digits alternately by 3 and 1, add them up, and the check digit is whatever brings the total to the next multiple of ten. For the EAN-13 data 590123412345 the weighted sum comes to 83, so the check digit is 7 and the full code is 5901234123457.

That scheme catches every single-digit error and most transpositions of adjacent digits, which are the two mistakes a human keying a number in tends to make. It does not catch a transposition of two digits that differ by 5, a known blind spot of alternating 3-and-1 weighting, which is one reason the code is meant to be scanned rather than keyed.

Code 128 does something different and stronger. Its check character is a weighted sum modulo 103 in which each symbol counts by its position, so an error in the fifth character and a compensating error in the ninth cannot cancel out. Code 39's modulo 43 check character is optional, and mostly unused, because a lot of the systems that still read Code 39 would report it as an extra character of data.

How Each Symbology Protects Itself

Every symbology here also carries per-character structure, such as a fixed module count or a fixed number of wide elements. A reader checks that long before it reaches the check digit.

SymbologyCheck characterAdded automatically?
EAN-13, EAN-8, UPC-A, UPC-EModulo 10, weights 3 and 1Yes, it is part of the number
ITF-14 (GTIN-14)Modulo 10, weights 3 and 1Yes, it is part of the number
Code 128Modulo 103, weighted by positionYes, and never printed
Code 39Modulo 43Optional, off by default
ITF (generic)None definedNo, the application decides
CodabarNone definedNo, the application decides
📏

The white space is part of the barcode

The blank margin either side of a symbol is called the quiet zone, and it is specified, not decorative: 10 X-dimensions for Code 128, Code 39 and ITF, 9 for UPC, 11 on the left of an EAN-13. A scanner uses it to establish what "light" looks like before it starts measuring anything. Crop it to make a code fit a label and you get a symbol that reads perfectly on a white screen and fails against a printed background, which is one of the harder faults to diagnose because the barcode itself is untouched.

The Trick That Makes Code 128 Short

Code 128 covers the whole ASCII set in 11 modules per character, which is dense, but it has a second gear. The symbology defines three character sets that share one table of bar patterns: A holds capitals, digits, punctuation and the ASCII control codes, B swaps the control codes for lower case, and C encodes nothing but digits, two of them per symbol.

That last one is why a numeric Code 128 is about half the width you would expect. A twelve-digit code in subset B needs twelve symbols; in subset C it needs six. Switching sets costs one symbol, so the break-even is four digits: a run of four or more pays for the switch and then keeps saving.

A good encoder does this without being asked. It starts in whichever set the data opens with, drops into C the moment a long enough digit run appears, comes back out for the letters, and where a single stray character needs the other set it uses the shift code rather than switching twice. Two encoders can make different legal choices here and both be correct: the symbol will differ, the decoded string will not.

How Small You Can Print It

This is the question that decides whether a barcode works, and pixels cannot answer it. What matters is the X-dimension on paper.

The GS1 General Specifications set the floor for a retail point-of-sale symbol at 0.264mm and call 0.33mm the nominal size, with a permitted range up to 0.66mm for larger packaging. Below that floor, two things go wrong at once: the printer's ink spreads and starts closing the gaps between bars, and the scanner's aperture stops resolving individual elements cleanly. ISO/IEC 15416, the print quality standard, grades a finished symbol from A to F on exactly those properties (edge contrast, modulation, decodability) by running a reference scan across it.

Height matters too, and it is the dimension people cut first. A scanner sweeping across a symbol at an angle needs to cross every bar in the same pass, so the taller the symbol, the more angles work. Roughly 15% of the symbol's width is the usual guidance, and EAN and UPC have a nominal height fixed outright. A truncated barcode still decodes; it just needs the beam to cross it squarely, which is why the person at the till passes it over the glass three times.

When the Number Needs to Say What It Is

A GTIN identifies a product. It does not carry a batch, an expiry date or a weight, and a warehouse usually needs all four. GS1-128 is the answer: an ordinary Code 128 that opens with the FNC1 character and then holds a sequence of element strings, each beginning with a two to four digit Application Identifier naming what comes after it. (01) is a GTIN, (17) an expiry date as YYMMDD, (10) a batch, (3103) a net weight in kilograms to three decimal places.

The hard part is not the identifiers, it is knowing where each field stops. Some AIs have a predefined element string length, so a reader counts out the right number of characters and moves on. Every other AI is variable length and has to be closed with an FNC1 separator when something follows it. Miss one and the symbol still scans: it just hands the receiving system a batch number with the next field glued onto the end.

Two details catch people out. Predefined length is decided by the AI’s first two digits rather than by the AI, so (402) needs a separator despite carrying a fixed seventeen digits, because the prefix 40 is not a predefined-length prefix. And the last element never takes a trailing separator, so the order you write the fields in changes how long the symbol comes out: put the shortest variable-length field last and you save a character.

🔍

A barcode reads the same upside down in brightness

Code 128, Code 39, ITF and Codabar are all decoded from the widths of their bars and spaces, and inverting a symbol leaves every one of those widths untouched. A photographic negative of a Code 128 therefore decodes to exactly the same string. That is why light bars on a dark background cannot be caught by decoding a symbol, and why a reader calibrates on the quiet zone instead: the blank margin is the light reference, and if it comes back dark the reader knows it is looking at the wrong polarity. EAN and UPC escape this because they match literal guard bit patterns rather than run lengths.

Which Symbology You Actually Need

Most of the time this is not a preference. Either something outside your control has already specified the format, or the code is internal and one answer is clearly best.

1

Code 128: anything internal

Full ASCII, the densest numeric encoding of the common symbologies, a strong check character, and universal scanner support. If nobody is forcing your hand, this is the answer.

2

EAN-13 and UPC-A: retail products

Not a choice and not something you can invent. The leading digits identify the company that owns the number, and they are issued by GS1 member organisations. EAN-13 outside North America, UPC-A within it, though modern tills read both.

3

ITF-14: the shipping carton

Carries the GTIN-14 of a case rather than an item. It is built for direct printing onto corrugated board, where the surface is rough and the print is coarse, and it is normally drawn with a bearer bar around it.

4

Code 39: older industrial systems

Digits, capitals and a handful of symbols, no more. It is wider than Code 128 for the same data and has no mandatory check character, so it survives mainly where a standard written decades ago still names it.

5

Codabar: libraries, blood banks and labs

Predates most of the others and persists in specific industries because their existing databases and readers assume it. Each symbol is wrapped in one of four start/stop letters, which those systems use to signal what kind of number it holds.

🧱

Why ITF symbols get a frame around them

ITF interleaves a pair of digits into one block, half in the bars and half in the spaces, with nothing marking where one character ends. A beam that crosses the symbol diagonally and exits partway along can therefore collect something that looks like a complete, valid, shorter number. That is a short scan. The bearer bar is the solid frame around the symbol, and a scan that leaves through it is thrown away rather than reported. On a carton read in motion, that frame is doing real work.

Draw one and check the numbers

Eleven symbologies, check digits worked out or verified, quiet zones drawn in, and the printed size in millimetres before you commit to a print run.

Open the Barcode Generator →

Frequently Asked Questions

Related Tools

Keep Reading