
I built a barcode generator this week, and the first thing the decoder taught me is that an EAN-13 doesn't draw thirteen digits. It draws twelve. You type 4006381333931, the printer puts 95 stripes on the label, and if you count the digit cells in them you get twelve.
The thirteenth digit is in there. It's just not drawn as a digit. It's hidden in which way round the other six on the left are written, and a scanner reads it back out of that.
I'd been holding these up to supermarket scanners for thirty years without knowing that. Here's how it works, and the number I got wrong that would have quietly made every EAN-13 the tool printed too narrow.
Ninety Five Stripes, Twelve Cells
An EAN-13 is exactly 95 modules wide. A module is the width of the narrowest bar, and every bar and every space is a whole number of them.
Count from the left. Three modules of guard, bar space bar. Six digit cells of seven modules each, 42. A five module centre guard. Six more cells, another 42. The closing guard, three. 3 plus 42 plus 5 plus 42 plus 3 is 95.
Twelve cells. Thirteen digits. One of them has nowhere to go.
Where the First Digit Went
Each seven module cell holds two bars and two spaces, and there are three alphabets a cell can be written in. The standard calls them L, G and R.
Set L is the plain one: an odd number of dark modules, starting with a space and ending with a bar. Set R is L with every module flipped, so even parity, starting with a bar. Set G is R written backwards, which starts with a space and ends with a bar like L does, but carries R's even parity.
The six cells on the right always use R. The six on the left use some mix of L and G, and the mix is not up to you. The first digit of the number picks it from a table.
| First digit | Left six cells |
|---|---|
| 0 | L L L L L L |
| 1 | L L G L G G |
| 2 | L L G G L G |
| 3 | L L G G G L |
| 4 | L G L L G G |
| 5 | L G G L L G |
| 6 | L G G G L L |
| 7 | L G L G L G |
| 8 | L G L G G L |
| 9 | L G G L G L |
So 4006381333931 draws its second to seventh digits, 0 0 6 3 8 1, in the pattern L G L L G G, because the first digit is 4. The 4 itself is never drawn. A scanner reads the six left cells, notes which ones came out odd and which came out even, looks that sequence up, and writes the 4 down.
That table is the whole trick, and it's where a hand written encoder goes wrong first. One wrong letter in row 7 and every product starting with 7 scans as something else.
Why the Scanner Doesn't Care Which Way Up
There's a second thing that table buys you. Every left hand cell, L or G, starts with a space and ends with a bar. Every right hand cell starts with a bar and ends with a space.
Hold the label upside down and the scanner reads the right half first, but a right half cell read backwards looks like no left half cell, so the reader knows within seven modules that the symbol is inverted and flips it. That's why a checkout scanner doesn't care how the cashier holds the packet.
The Check Digit Is a Sum
The last digit is the one people know about, and most of them treat it as "whatever the generator puts there". It's a sum.
Take the twelve digits before it. Starting from the rightmost, weight them three, one, three, one, and so on back to the left. Add it all up. The check digit is whatever brings the total up to the next multiple of ten.
For 400638133393 the weighted products are 4, 0, 0, 18, 3, 24, 1, 9, 3, 9, 9 and 9. They add up to 89. The next multiple of ten is 90, so the check digit is 1 and the full number is 4006381333931.
Because the weights run from the right, padding a number with a zero on the left changes nothing. A UPC-A is twelve digits, and it's the same symbol as an EAN-13 that starts with 0, with the same check digit at the end. 036000291452 and 0036000291452 both end in 2. That's why a scanner sold in Europe reads an American packet without a second mode.
Now swap two neighbours. One was on a three and the other on a one, so the total moves by twice their difference, and twice a difference is a multiple of ten only when the difference is five. Swap a 2 and a 7 and the check digit still passes. Swap anything else and it fails, and a number that fails its own check is a number the scanner refuses.
The tool works the digit out when you give it twelve and checks it when you give it thirteen. If yours is wrong it says which digit it expected, because silently correcting it would print a label for a different product.
What "Printed at 100 Percent" Means
A barcode is a physical object, and the number that matters is the X dimension, the width of one module in millimetres. GS1 publishes a dimension table for EAN-13, and at 100 percent magnification it reads like this.
| Magnification | X dimension | Bars | Left quiet zone | Right quiet zone |
|---|---|---|---|---|
| 80% | 0.26 mm | 25.08 mm | 2.90 mm | 1.85 mm |
| 100% | 0.33 mm | 31.35 mm | 3.63 mm | 2.31 mm |
| 150% | 0.50 mm | 47.03 mm | 5.45 mm | 3.47 mm |
| 200% | 0.66 mm | 62.70 mm | 7.26 mm | 4.62 mm |
The bar height at 100 percent is 22.85 mm, and the guard bars run 5 modules further down than the rest, the little drop you can see under the digits on any packet. The retail range is 80 to 200 percent, and below it the sheet is blunt:
For all other printing processes, an X-dimension of 0.264 millimetre (magnification of 80%) is attainable and is the minimum allowable size.
Divide the widths by the X dimension and the table turns into module counts. 31.35 divided by 0.33 is 95, the bars. 3.63 divided by 0.33 is 11, the left quiet zone. 2.31 divided by 0.33 is 7, the right one. Add them up and you get 113 modules, and 113 times 0.33 is 37.29 mm, which is the figure you'll see quoted as "the size of an EAN-13". It's the bars plus the white space either side. If you're laying out a package, 37.29 is the number you need. If you're writing an encoder, 95 is.
The Nine That Should Have Been Eleven
Here's the one I got wrong.
I'd written the brief for the encoder from memory, and I wrote "nine modules of quiet zone on the left, seven on the right". Nine is the UPC-A figure. UPC-A has nine on each side. EAN-13 has eleven on the left and seven on the right, and I'd blended the two.
The module that caught it was the one that works out print sizes. It was written from the published widths, and it did the division above on its own: 37.29 over 0.33 is 113, 113 minus 95 is 18, and 18 is 11 plus 7. Its comment said eleven. The encoder's table said nine. Only one of them could reproduce a number that appears in the specification.
With nine, an EAN-13 with its quiet zone came out at 111 modules, 36.63 mm. That figure is in no table anywhere. The regression test now asserts 113 and asserts that 113 times 0.33 rounds to 37.29, and its comment explains why, so the next person who "corrects" it back to nine has to argue with GS1 rather than with me.
Two thirds of a millimetre. Nobody would have noticed for months. A label designed to the wrong quiet zone is a label where the artwork can sit 0.66 mm closer than it should, which is the kind of thing that reads on the bench and fails on the shelf.
The Quiet Zone Is Part of the Barcode
That one needs saying plainly, because it's the first reason a printed barcode won't scan, and people cut it on purpose.
The white margins either side are the symbol. A reader finds the start and the stop by seeing a stretch of nothing, then a bar. Trim the margin to make room for a logo and the reader sees the logo's edge as a bar, and what it decodes is garbage or, worse, a different number.
The tool keeps the quiet zone on by default and draws it into the file, so the SVG you download is 113 modules wide rather than 95. Turn it off and the page says that whatever you place the symbol on now has to leave that space clear itself.
Reading It Back
Drawing the right bars is the part that ruins a print run, so every barcode the tool makes goes through a second piece of code that knows nothing about how it was drawn.
That code reads the 95 modules the way a scanner would. It finds the guards, cuts the twelve cells out, works out the parity of the six on the left, looks the sequence up in the table above, writes down the first digit, decodes the other twelve and checks the sum. The page then compares that with what you typed. If they match, it prints the number the decoder saw. If they don't, you get a warning instead of a barcode.
Every number in the test suite goes through the encoder and back through the decoder, because a test written by the person who typed the table would happily encode the same typo.
The Number Itself Is Not Yours Until GS1 Says So
One thing the tool can't do, and it says so on the page. It draws the symbol for a number. It doesn't give you the number.
Real retail numbers come from GS1, who issue the company prefix that makes a range yours. GS1 US puts it plainly:
Retailers, online marketplaces, distributors, and other partners often require UPC barcodes that come specifically from GS1 because it shows that you are a business they can trust.
And on what happens when the number isn't registered to you: "you may risk rejection, or worse, you may incur additional costs to relabel your products". People find that out after the labels are printed, and I'd rather they read it before.
When You Don't Need GS1 at All
Most people arriving at a barcode generator don't want a retail number. They want a sticker on a shelf or a jar, and the only scanner that will ever read it is their own. None of that touches GS1.
| Symbology | Made for | Who reads it | Needs a licence |
|---|---|---|---|
| EAN-13 | A product sold at retail, most of the world | Any checkout scanner | Yes, from GS1 |
| UPC-A | The same, in the United States and Canada | Any checkout scanner | Yes, from GS1 |
| ITF-14 | The outer shipping carton | A warehouse scanner | Yes, it carries the GS1 number |
| Code 128 | An internal SKU, an asset tag, a bin | Your own scanner | No |
| Code 39 | An older system that asks for it by name | Your own scanner | No |
| QR | Anything a phone camera should open | A phone | No |
Code 128 is the one to reach for when nobody outside your building has to read the label. It takes letters as well as digits, and packs a long number into half the width by pairing them up.
The Sheet Is the Part People Actually Wanted
Every free generator makes one barcode. What people type into the search box, judging by the autocomplete, is barcode generator excel: a whole column of them, out of a spreadsheet.
So the tool takes a column. Paste one out of a spreadsheet, or type 1000-1050 and get the whole range. A CSV works too. A comma and a caption on any line prints the caption under the symbol. Pick the stock, Avery 5160, 5163, 5167, L7160 or L7651, and download one PDF with every code in its slot. Peeled six off the sheet last week? Tell it to skip six.
The PDF is vector, every bar a drawn rectangle rather than a picture of one, so a label printer rips it the way it rips text. One free generator I checked gives you a GIF, a JPG or a PNG, keeps SVG for subscribers and caps you at ten codes unless you register, in its own words. Here SVG is the default.
Leading zeros survive all of it. 0071234 goes in and 0071234 comes out, because nothing in the pipeline reads a code as a number. I learned that one on the CSV viewer and wasn't going to learn it twice.
Before You Print Ten Thousand Labels
- Know whose number it is. If it's going on a retail shelf, it came from GS1 or it's going to be rejected. If it's for your own scanner, use Code 128 and skip the whole question.
- Give the tool twelve digits and let it add the thirteenth. If you already have all thirteen, let it check them, and if it names a different digit, believe it.
- Keep the quiet zone. Eleven modules on the left, seven on the right. If your artwork can't leave that clear, the artwork is wrong.
- Pick an X dimension and read the millimetres. Between 0.264 and 0.660 mm for retail, and check the dot count for your printer before you trust the size.
- Print one sheet, scan it with your phone, then print the rest.
The generator is at /tools/barcode-generator. It runs in the tab, nothing is uploaded, and there's no watermark.
One Last Thing
Thirteen digits, twelve drawn. The first lives in the parity of six others, the last is a sum of the rest, and neither is optional.
I got the white space wrong by two modules and a second file caught it by dividing two published numbers. That's the reason the decoder exists: an encoder can be confident and wrong at the same time, and a label doesn't care how confident it was.
Draw the bars, then read them back. Then print.
Last updated: September 10, 2026 | Reading time: 12 minutes
Written by Evgeniy Poznyak, who spent an afternoon finding out that nine is not eleven.