The UPC-A bar code used in the United States. It only has 11 digits
plus the key. It is in reality an EAN13 code whose first digit would be zero and whose presentation
would be slightly different. The UPC-A code is a subset of the EAN13 code.
Example :
These two barcodes are identical, a zero has been added before the
UPC-A code to create the EAN13 code, but the bar pattern is exactly the same.
Since early 2005, all stores in the United States have been required to accept the
EAN13 code, so there is no longer any reason to produce UPC-A codes.
Meaning of the numbers.
- 2 digits for the country code or system code
- 5 digits for the company identifier
- 5 digits for the item identifier
- 1 digit for the checksum
This rule is subject to numerous exceptions to improve the use of available numbers.
Here is the list of country or system codes.
00 à 13 UCC (United States and Canada)
20 à 29 Internal store coding
30 à 37 GENCOD-EAN France
380 BCCI (Bulgaria)
383 SANA (Slovenia)
385 CRO-EAN(Croatia)
387 EAN-BIH (Bosnia and Herzegovina)
400 à 440 CCG (Germany)
45 + 49 Distribution Code Center DCC (Japan)
460 to 469 UNISCAN - EAN Russia (Russian Federation)
471 CAN (Taiwan)
474 EAN Estonia
475 EAN Latvia
476 EAN Azerbaidjan
477 EAN Lituania
478 EAN Uzbekistan
479 EAN Sri Lanka
480 PANC (Philippines)
481 EAN Belarus
482 EAN Ukraine
484 EAN Moldova
485 EAN Armenia
486 EAN Georgia
487 EAN Kazakhstan
489 HKANA (Hong Kong)
50 E Centre UK
520 HELLCAN-EAN HELLAS (Greece)
528 EAN Lebanon
529 EAN Cyprus
531 EAN-MAC (FYR Macedonia)
535 EAN Malta
539 EAN Ireland
54 ICODIF/EAN Belgium. Luxembourg
560 CODIPOR (Portugal)
569 EAN Iceland
57 EAN Denmark
590 EAN Poland
594 EAN Romania
599 H.A.P.M.H. (Hungary)
600 - 601 EAN South Africa
609 EAN Mauritius
611 EAN Morocco
613 EAN Algeria
619 Tunicode (Tunisia)
621 EAN Syria
622 EAN Egypt
625 EAN Jordan
626 EAN Iran
628 EAN Saudi Arabia
64 EAN Finland
690 - 693 Article Numbering Centre of China - ANCC (China)
70 EAN Norge (Norway)
729 Israeli Bar Code Association EAN Israel
l73 EAN Sweden
740 EAN Guatemala
741 EAN El Salvador
742 ICCC (Honduras)
743 EAN Nicaragua
744 EAN Costa Rica Panama
746 746 EAN Dominican Republic
750 AMECE (Mexico)
759 EAN Venezuela
76 EAN (Schweiz, Switzerland, Svizzera)
770 IAC (Colombia)
773 EAN Uruguay
775 APC - EAN Peru (Peru)
777 EAN Bolivia
779 CODIGO - EAN Argentina
780 EAN Chile
784 EAN Paraguay
786 ECOP (Ecuador)
789 EAN Brazil
80 à 83 INDICOD (Italy)
84 AECOC (Spain)
850 Camera de Comercio de la Republica de Cuba (Cuba)
858 EAN Slovakia
859 EAN Czech Republic
860 EAN YU (Yugoslavia)
867 EAN DPR Korea (North Korea)
869 Union of Chambers of Commerce of Turkey (Türkiye)
)87 EAN Nederland (Holland)
880 EAN Korea (South Korea)
885 EAN Thailand
888 SANC (Singapore)
890 EAN India
893 EAN Vietnam
99 EAN Indonesia
90 - 91 EAN Austria
93 EAN Australia
94 EAN New Zealand
955 Malaysian< Article Numbering Council (MANC) - Malaysia
977 Serial publications (ISSN)
978 - 979 Books (ISBN)
980 Refund Receipts
981 - 982 Coupons (current currency)
99 Coupons
Let's now look at the calculation of the checksum.
The numbers are numbered from right to left.
Let x be the sum of the even digits and y the sum of the odd digits.
Let's calculate z = x + 3*y
Let m be the number divisible by 10 immediately greater than z
The checksum is : m - z
Example : 978020113447
x = 4 + 3 + 1 + 2 + 8 + 9 = 27
y = 7 + 4 + 1 + 0 + 0 + 7 = 19
z = 3 * 19 + 27 = 84
m = 90
Checksum = 90 - 84 = 6
EAN13 ---> 9 780201 134476
Next, let's examine the encoding system.
- The first digit is not coded but it determines the tables to be used for coding the following 6 digits.
- The width of a thin bar (0.33 mm standard) is called the module.
- There are bars of 1, 2, 3 or 4 modules; the same applies to spaces.
- Each number is coded on 7 modules, each comprising 2 bars and two spaces.
Let's symbolize the bar module by «1» and the space module by «0».
- The start and end markers are : «101»
- The separator mark placed in the middle after the 7th digit is : «01010»
- The total length is always 12 * 7 + 2 * 3 + 5 = 95 modules ; there are always 30 bars in total.
- The separator bars are 5 modules longer than the other bars.
- You need white margins of at least 11 modules on the left and 7 modules on the right.
The numbers are converted according to one of the 3 tables below; the codes in tables A and B start with a space while those in table C start with a bar.
Digit
Table A
Table B
Table C
0
0001101
0100111
1110010
1
0011001
0110011
1100110
2
0010011
0011011
1101100
3
0111101
0100001
1000010
4
0100011
0011101
1011100
5
0110001
0111001
1001110
6
0101111
0000101
1010000
7
0111011
0010001
1000100
8
0110111
0001001
1001000
9
0001011
0010111
1110100
The first digit is not coded; each of the following six digits is converted using either Table A or Table B, depending on the first digit. The last six digits are converted
using Table C.
A new table indicates the use of tables A or B for digits No. 2 to No. 7 depending on digit No. 1
Digit No.1
No.2
No.3
No.4
No.5
No.6
No.7
0
A
A
A
A
A
A
1
A
A
B
A
B
B
2
A
A
B
B
A
B
3
A
A
B
B
B
A
4
A
B
A
A
B
B
5
A
B
B
A
A
B
6
A
B
B
B
A
A
7
A
B
A
B
A
B
8
A
B
A
B
B
A
9
A
B
B
A
B
A
Some EAN13 codes are followed by a «supplement» of 2 or 5 digit particularly on books and magazines.
This supplement is coded using tables A and B. The choice of table A or B for each digit of the supplement depends on a checksum that must be calculated.
Two-digit supplement.
Checksum calculation :
Let
xbe the value of the supplement
Let
m be the number divisible by 4 immediately less than
x
The checksum is :
x - m
Example :
x = 35 --> m = 32
Checksum = 35 - 32 = 3
Checksum
Digit 1
Digit 2
0
A
A
1
A
B
2
B
A
3
B
B
Five-digit supplement.
Checksum calculation :
Let
xbe the sum of the even digits and
y the sum of the odd digits.
Let's calculate
z = 9 * x + 3 * y
Let
m be the number divisible by 10 immediately less than
z
The checksum is :
z - m
Example :
Supplement = 12345
x = 2 + 4 = 6 et y = 1 + 3 + 5 = 9 donc z = 9 * 6 + 3 * 9 = 81
Checksum = 81 - 80 = 1
Checksum
Digit No.1
No.2
No.3
No.4
No.5
0
B
B
A
A
A
1
B
A
B
A
A
2
B
A
A
B
A
3
B
A
A
A
B
4
A
B
B
A
A
5
A
A
B
B
A
6
A
A
A
B
B
7
A
B
A
B
A
8
A
B
A
A
B
9
A
A
B
A
B
In addition, a supplement begins with a special 4-module delimiter whose formula is : 1011 and each character, except the last, is followed by a formula separator 01.
The creation of barcodes.
Since we can create the barcode pattern it remains us to draw it on the screen and to print it on a paper sheet. Two approaches are possibles :
-
The graphic method where each bar is "drawn" as a full rectangle. This method enable to compute the width of each bar with a one pixel precision and so we can work with widths which
are perfect multiple of the used device pixel. This give us a good accuracy specially if the device have a low density as it's the case with screens and inkjet printers. This method
require special programming routines and does not allow to make bar codes with a current software.
-
The special font in which each character is replaced by a barcode. This method allow the use of any software like a text processing or a spreadsheet. (For example LibreOffice, the
free clone of MSoffice !) The scale settings according to the selected size can bring away small misshaping of the bar drawing. With a laser printer there's no probs.
Most fonts for EAN barcodes found on the net (incomplete demo fonts) are paid (sometimes very expensive) and of questionable quality ;
width of the modules is not always constant in the definition of the font. So I decided to completely design an EAN13 font and offer it in
download. I tested it on a 14 body laser printer, which gives a very small barcode of around 13mm wide, result:
100% reading! On a good inkjet printer, this same body of 14 works perfectly.
The font " EAN13.ttf "
This font contain the 5 sets of the 10 digits for the 3 tables A, B and C learned above and 2 tables for the first digit (Table D & E)
- Table A : Set of code A with the digit under the barcode.
- Table B : Set of code B with the digit under the barcode.
- Table C : Set of code C with the digit under the barcode.
- Table D : Set of digits with the start delimiter
- Table E : Set of digits without the start delimiter (Requested for the SAGE softwares)
The following table indicates the correspondence between the drawned bar code and the typed letter (ASCII code between bracket)
Digit
Table A
Table B
Table C
Table D
Table E
0
A (65)
K (75)
a (97)
0 (48)
k (107)
1
B (66)
L (76)
b (98)
1 (49)
l (108)
2
C (67)
M (77)
c (99)
2 (50)
m (109)
3
D (68)
N (78)
d (100)
3 (51)
n (110)
4
E (69)
O (79)
e (101)
4 (52)
o (111)
5
F (70)
P (80)
f (102)
5 (53)
p (112)
6
G (71)
Q (81)
g (103)
6 (54)
q (113)
7
H (72)
R (82)
h (104)
7 (55)
r (114)
8
I (73)
S (83)
i (105)
8 (56)
s (115)
9
J (74)
T (84)
j (106)
9 (57)
t (116)
Additional
codes
: (58)
Start delimiter (For SAGE software)
* (42)
Middle delimiter
+ (43)
End delimiter
[ (91)
Supplement start delimiter
\ (92)
Character separator in the supplement
Copy this file in the font directory, often named : : \Windows\Fonts
The alone start delimiter (Code 58) and the table E were added for
the
SAGE software user who will have to then
configure in their software the EAN13 encoding font table as follows :
Position
1
2
3
4
5
6
7
8
9
Value
[
:
A
K
*
a
+
k
]
Structure of an EAN13 barcode
An EAN13 barcode will be build up in the following way :
- Digit number 1 from table D (Left quiet zone and start delimiter included)
- 6 digits from tables A or B according to the first digit
- Middle delimiter
- 6 digits from table C
- End delimiter (Right quiet zone included)
A small program to test all that
Here is a small program written with Visual Basic 6.
The setup file copy the program, Visual Basic
dependencies, source files and the font.
Setup file :
ZIP file without setup :
The EAN13$ function can be re-used in any other Visual Basic 6 program ; it can also be recopied just as it in a VBA macro linked to an Excel or Word document.
Public Function ean13$(chaine$)
'Cette fonction est régie par la Licence Générale Publique Amoindrie GNU (GNU LGPL)
'This function is governed by the GNU Lesser General Public License (GNU LGPL)
'V 1.1.1
'Paramètres : une chaine de 12 chiffres
'Parameters : a 12 digits length string
'Retour : * une chaine qui, affichée avec la police EAN13.TTF, donne le code barre
' * une chaine vide si paramètre fourni incorrect
'Return : * a string which give the bar code when it is dispayed with EAN13.TTF font
' * an empty string if the supplied parameter is no good
Dim i%, checksum%, first%, CodeBarre$, tableA As Boolean
ean13$ = ""
'Vérifier qu'il y a 12 caractères
'Check for 12 characters
If Len(chaine$) = 12 Then
'Et que ce sont bien des chiffres
'And they are really digits
For i% = 1 To 12
If Asc(Mid$(chaine$, i%, 1)) < 48 Or Asc(Mid$(chaine$, i%, 1)) > 57 Then
i% = 0
Exit For
End If
Next
If i% = 13 Then
'Calcul de la clé de contrôle
'Calculation of the checksum
For i% = 12 To 1 Step -2
checksum% = checksum% + Val(Mid$(chaine$, i%, 1))
Next
checksum% = checksum% * 3
For i% = 11 To 1 Step -2
checksum% = checksum% + Val(Mid$(chaine$, i%, 1))
Next
chaine$ = chaine$ & (10 - checksum% Mod 10) Mod 10
'Le premier chiffre est pris tel quel, le deuxième vient de la table A
'The first digit is taken just as it is, the second one come from table A
CodeBarre$ = Left$(chaine$, 1) & Chr$(65 + Val(Mid$(chaine$, 2, 1)))
first% = Val(Left$(chaine$, 1))
For i% = 3 To 7
tableA = False
Select Case i%
Case 3
Select Case first%
Case 0 To 3
tableA = True
End Select
Case 4
Select Case first%
Case 0, 4, 7, 8
tableA = True
End Select
Case 5
Select Case first%
Case 0, 1, 4, 5, 9
tableA = True
End Select
Case 6
Select Case first%
Case 0, 2, 5, 6, 7
tableA = True
End Select
Case 7
Select Case first%
Case 0, 3, 6, 8, 9
tableA = True
End Select
End Select
If tableA Then
CodeBarre$ = CodeBarre$ & Chr$(65 + Val(Mid$(chaine$, i%, 1)))
Else
CodeBarre$ = CodeBarre$ & Chr$(75 + Val(Mid$(chaine$, i%, 1)))
End If
Next
CodeBarre$ = CodeBarre$ & "*" 'Ajout séparateur central / Add middle separator
For i% = 8 To 13
CodeBarre$ = CodeBarre$ & Chr$(97 + Val(Mid$(chaine$, i%, 1)))
Next
CodeBarre$ = CodeBarre$ & "+" 'Ajout de la marque de fin / Add end mark
ean13$ = CodeBarre$
End If
End If
End Function
Demo Excel file
File for Libre Office
Since the first publication of this page, I have received numerous versions in different languages; here they are :
Language
Author
Neobook 4
Jean-Louis HUVE
Visual Foxpro
Emile MAITREJEAN
Delphi
John SWIJSEN
Delphi
YARDIMLI EKIM
Delphi
Francisco FERNANDEZ
C#
Russell SAYERS
Perl
Simone FIORAVANTI
Axapta
Søe JESPER
The EAN 8 code
It closely resembles the EAN 13 code. It consists of 7 digits and a checksum calculated in exactly the same way as for the EAN13 code. The left (ASCII 58
will be used), middle, and right delimiters are the same. The first 4 digits are constructed using table A and the last 4 using table C.
We will therefore also use the EAN13 font with this function :
Public Function EAN8$(chaine$)
'V 1.0.0
'Paramètres : une chaine de 7 chiffres
'Parameters : a 7 digits length string
'Retour : * une chaine qui, affichée avec la police EAN13.TTF, donne le code barre
' * une chaine vide si paramètre fourni incorrect
'Return : * a string which give the bar code when it is dispayed with EAN13.TTF font
' * an empty string if the supplied parameter is no good
Dim i%, checksum%, first%, CodeBarre$, tableA As Boolean
EAN8$ = ""
'Vérifier qu'il y a 7 caractères
'Check for 7 characters
If Len(chaine$) = 7 Then
'Et que ce sont bien des chiffres
'And they are really digits
For i% = 1 To 7
If Asc(Mid$(chaine$, i%, 1)) < 48 Or Asc(Mid$(chaine$, i%, 1)) > 57 Then
i% = 0
Exit For
End If
Next
If i% = 8 Then
'Calcul de la clé de contrôle
'Calculation of the checksum
For i% = 7 To 1 Step -2
checksum% = checksum% + Val(Mid$(chaine$, i%, 1))
Next
checksum% = checksum% * 3
For i% = 6 To 1 Step -2
checksum% = checksum% + Val(Mid$(chaine$, i%, 1))
Next
chaine$ = chaine$ & (10 - checksum% Mod 10) Mod 10
'Les 4 premier chiffre viennent de la table A
'The first 4 digits come from table A
CodeBarre$ = "" 'Ajout marque de début / Add start mark
For i% = 1 To 4
CodeBarre$ = CodeBarre$ & Chr$(65 + Val(Mid$(chaine$, i%, 1)))
Next
CodeBarre$ = CodeBarre$ & "*" 'Ajout séparateur central / Add middle separator
For i% = 5 To 8
CodeBarre$ = CodeBarre$ & Chr$(97 + Val(Mid$(chaine$, i%, 1)))
Next
CodeBarre$ = CodeBarre$ & "+" 'Ajout de la marque de fin / Add end mark
EAN8$ = CodeBarre$
End If
End If
End Function