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.
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 whether Table A or B was used, depending on the first digit.
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.
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 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
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.
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 :
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.
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)
The following table indicates the correspondence between the drawned bar code and the typed letter (ASCII code between bracket)
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 :
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
Since the first publication of this page, I have received numerous versions in different languages; here they are :
Visual Foxpro
Emile MAITREJEAN
Delphi
John SWIJSEN
Delphi
YARDIMLI EKIM E YARDIMLI
Delphi
Francisco FERNANDEZ
C#
Russell SAYERS
Perl
Simone FIORAVANTI
Axapta
Søe JESPER
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