|
This complex code allows the coding of the 128 ASCII characters. The result is very dense, in particular for the coding of the numerical values. It is used amongst other things on certain sheet of social security (in France) and certain transport label to register the SSCC number. (Identifier of the parcel)
Value | Table A | Table B | Table C | ASCII Code | Character | Pattern | Value | Table A | Table B | Table C | ASCII Code | Character | Pattern | |
0 | Space | Space | 00 | 0032 or 0212 | Space or O | 11011001100 | 54 | V | V | 54 | 0086 | V | 11101011000 | |
1 | ! | ! | 01 | 0033 | ! | 11001101100 | 55 | W | W | 55 | 0087 | W | 11101000110 | |
2 | " | " | 02 | 0034 | " | 11001100110 | 56 | X | X | 56 | 0088 | X | 11100010110 | |
3 | # | # | 03 | 0035 | # | 10010011000 | 57 | Y | Y | 57 | 0089 | Y | 11101101000 | |
4 | $ | $ | 04 | 0036 | $ | 10010001100 | 58 | Z | Z | 58 | 0090 | Z | 11101100010 | |
5 | % | % | 05 | 0037 | % | 10001001100 | 59 | [ | [ | 59 | 0091 | [ | 11100011010 | |
6 | & | & | 06 | 0038 | & | 10011001000 | 60 | \ | \ | 60 | 0092 | \ | 11101111010 | |
7 | ' | ' | 07 | 0039 | ' | 10011000100 | 61 | ] | ] | 61 | 0093 | ] | 11001000010 | |
8 | ( | ( | 08 | 0040 | ( | 10001100100 | 62 | ^ | ^ | 62 | 0094 | ^ | 11110001010 | |
9 | ) | ) | 09 | 0041 | ) | 11001001000 | 63 | _ | _ | 63 | 0095 | _ | 10100110000 | |
10 | * | * | 10 | 0042 | * | 11001000100 | 64 | nul | ` | 64 | 0096 | ` | 10100001100 | |
11 | + | + | 11 | 0043 | + | 11000100100 | 65 | soh | a | 65 | 0097 | a | 10010110000 | |
12 | , | , | 12 | 0044 | , | 10110011100 | 66 | stx | b | 66 | 0098 | b | 10010000110 | |
13 | - | - | 13 | 0045 | - | 10011011100 | 67 | etx | c | 67 | 0099 | c | 10000101100 | |
14 | . | . | 14 | 0046 | . | 10011001110 | 68 | eot | d | 68 | 0100 | d | 10000100110 | |
15 | / | / | 15 | 0047 | / | 10111001100 | 69 | eno | e | 69 | 0101 | e | 10110010000 | |
16 | 0 | 0 | 16 | 0048 | 0 | 10011101100 | 70 | ack | f | 70 | 0102 | f | 10110000100 | |
17 | 1 | 1 | 17 | 0049 | 1 | 10011100110 | 71 | bel | g | 71 | 0103 | g | 10011010000 | |
18 | 2 | 2 | 18 | 0050 | 2 | 11001110010 | 72 | bs | h | 72 | 0104 | h | 10011000010 | |
19 | 3 | 3 | 19 | 0051 | 3 | 11001011100 | 73 | ht | i | 73 | 0105 | i | 10000110100 | |
20 | 4 | 4 | 20 | 0052 | 4 | 11001001110 | 74 | lf | j | 74 | 0106 | j | 10000110010 | |
21 | 5 | 5 | 21 | 0053 | 5 | 11011100100 | 75 | vt | k | 75 | 0107 | k | 11000010010 | |
22 | 6 | 6 | 22 | 0054 | 6 | 11001110100 | 76 | ff | l | 76 | 0108 | l | 11001010000 | |
23 | 7 | 7 | 23 | 0055 | 7 | 11101101110 | 77 | cr | m | 77 | 0109 | m | 11110111010 | |
24 | 8 | 8 | 24 | 0056 | 8 | 11101001100 | 78 | s0 | n | 78 | 0110 | n | 11000010100 | |
25 | 9 | 9 | 25 | 0057 | 9 | 11100101100 | 79 | s1 | o | 79 | 0111 | o | 10001111010 | |
26 | : | : | 26 | 0058 | : | 11100100110 | 80 | dle | p | 80 | 0112 | p | 10100111100 | |
27 | ; | ; | 27 | 0059 | ; | 11101100100 | 81 | dc1 | q | 81 | 0113 | q | 10010111100 | |
28 | < | < | 28 | 0060 | < | 11100110100 | 82 | dc2 | r | 82 | 0114 | r | 10010011110 | |
29 | = | = | 29 | 0061 | = | 11100110010 | 83 | dc3 | s | 83 | 0115 | s | 10111100100 | |
30 | > | > | 30 | 0062 | > | 11011011000 | 84 | dc4 | t | 84 | 0116 | t | 10011110100 | |
31 | ? | ? | 31 | 0063 | ? | 11011000110 | 85 | nak | u | 85 | 0117 | u | 10011110010 | |
32 | @ | @ | 32 | 0064 | @ | 11000110110 | 86 | syn | v | 86 | 0118 | v | 11110100100 | |
33 | A | A | 33 | 0065 | A | 10100011000 | 87 | etb | w | 87 | 0119 | w | 11110010100 | |
34 | B | B | 34 | 0066 | B | 10001011000 | 88 | can | x | 88 | 0120 | x | 11110010010 | |
35 | C | C | 35 | 0067 | C | 10001000110 | 89 | em | y | 89 | 0121 | y | 11011011110 | |
36 | D | D | 36 | 0068 | D | 10110001000 | 90 | sub | z | 90 | 0122 | z | 11011110110 | |
37 | E | E | 37 | 0069 | E | 10001101000 | 91 | esc | { | 91 | 0123 | { | 11110110110 | |
38 | F | F | 38 | 0070 | F | 10001100010 | 92 | fs | | | 92 | 0124 | | | 10101111000 | |
39 | G | G | 39 | 0071 | G | 11010001000 | 93 | gs | } | 93 | 0125 | } | 10100011110 | |
40 | H | H | 40 | 0072 | H | 11000101000 | 94 | rs | ~ | 94 | 0126 | ~ | 10001011110 | |
41 | I | I | 41 | 0073 | I | 11000100010 | 95 | us | del | 95 | 0200 | E | 10111101000 | |
42 | J | J | 42 | 0074 | J | 10110111000 | 96 | Fnc 3 | Fnc 3 | 96 | 0201 | E | 10111100010 | |
43 | K | K | 43 | 0075 | K | 10110001110 | 97 | Fnc 2 | Fnc2 | 97 | 0202 | E | 11110101000 | |
44 | L | L | 44 | 0076 | L | 10001101110 | 98 | Shift | Shift | 98 | 0203 | E | 11110100010 | |
45 | M | M | 45 | 0077 | M | 10111011000 | 99 | Code C | Code C | 99 | 0204 | I | 10111011110 | |
46 | N | N | 46 | 0078 | N | 10111000110 | 100 | Code B | Fnc 4 | Code B | 0205 | I | 10111101110 | |
47 | O | O | 47 | 0079 | O | 10001110110 | 101 | Fnc 4 | Code A | Code A | 0206 | I | 11101011110 | |
48 | P | P | 48 | 0080 | P | 11101110110 | 102 | Fnc 1 | Fnc 1 | Fnc 1 | 0207 | I | 11110101110 | |
49 | Q | Q | 49 | 0081 | Q | 11010001110 | 103 | Start A | Start A | Start A | 0208 | D | 11010000100 | |
50 | R | R | 50 | 0082 | R | 11000101110 | 104 | Start B | Start B | Start B | 0209 | N | 11010010000 | |
51 | S | S | 51 | 0083 | S | 11011101000 | 105 | Start C | Start C | Start C | 0210 | O | 11010011100 | |
52 | T | T | 52 | 0084 | T | 11011100010 | 106 | Stop | Stop | Stop | 0211 | O | 1100011101011 | |
53 | U | U | 53 | 0085 | U | 11011101110 |
Exemple of checksum
with use of table B for : ZB65
104 + (1 x 58) + (2 x 34) + (3 x 22) +
(4 x 21) = 380
380
/ 103 = 3, remainder 71 which is the value of the key.
Version 2.00 of the font : The code of characters 95 and following was modified compared to the version 1.00. The encoding function was modified consequently.
Since we can create the bar code pattern it remains us to draw it on the screen and to print it on a paper sheet. Two approaches are possible :
All the found 128 barcodes on the net (Incomplete demonstration font) aren't free, several times expensive, and with uncertain quality; the width module isn't always permanent in the font definition. I've decided consequently to draw entirely a 128 font and to propose it for download. I test it on a laser printer with size 17, what gives a small barcode with a width of about 1,7 mm/car, result : reading at 100% ! On a good inkjet printer, we can go down (He yes !) to the size 15 what give a character width of 1,5mm.
This font contain the 107 patterns of the code. The START and STOP codes include the margins.
Copy this file |
A 128 barcode will be build up in the following way :
|
Here is a small program
|
Public Function Code128$(chaine$) 'V 2.0.0 'Parametres : une chaine 'Parameters : a string 'Retour : * une chaine qui, affichee avec la police CODE128.TTF, donne le code barre ' * une chaine vide si parametre fourni incorrect 'Return : * a string which give the bar code when it is dispayed with CODE128.TTF font ' * an empty string if the supplied parameter is no good Dim i%, checksum&, mini%, dummy%, tableB As Boolean Code128$ = "" If Len(chaine$) > 0 Then 'Verifier si caracteres valides 'Check for valid characters For i% = 1 To Len(chaine$) Select Case Asc(Mid$(chaine$, i%, 1)) Case 32 To 126, 203 Case Else i% = 0 Exit For End Select Next 'Calculer la chaine de code en optimisant l'usage des tables B et C 'Calculation of the code string with optimized use of tables B and C Code128$ = "" tableB = True If i% > 0 Then i% = 1 'i% devient l'index sur la chaine / i% become the string index Do While i% <= Len(chaine$) If tableB Then 'Voir si interessant de passer en table C / See if interesting to switch to table C 'Oui pour 4 chiffres au debut ou a la fin, sinon pour 6 chiffres / yes for 4 digits at start or end, else if 6 digits mini% = IIf(i% = 1 Or i% + 3 = Len(chaine$), 4, 6) GoSub testnum If mini% < 0 Then 'Choix table C / Choice of table C If i% = 1 Then 'Debuter sur table C / Starting with table C Code128$ = Chr$(210) Else 'Commuter sur table C / Switch to table C Code128$ = Code128$ & Chr$(204) End If tableB = False Else If i% = 1 Then Code128$ = Chr$(209) 'Debuter sur table B / Starting with table B End If End If If Not tableB Then 'On est sur la table C, essayer de traiter 2 chiffres / We are on table C, try to process 2 digits mini% = 2 GoSub testnum If mini% < 0 Then 'OK pour 2 chiffres, les traiter / OK for 2 digits, process it dummy% = Val(Mid$(chaine$, i%, 2)) dummy% = IIf(dummy% < 95, dummy% + 32, dummy% + 105) Code128$ = Code128$ & Chr$(dummy%) i% = i% + 2 Else 'On n'a pas 2 chiffres, repasser en table B / We haven't 2 digits, switch to table B Code128$ = Code128$ & Chr$(205) tableB = True End If End If If tableB Then 'Traiter 1 caractere en table B / Process 1 digit with table B Code128$ = Code128$ & Mid$(chaine$, i%, 1) i% = i% + 1 End If Loop 'Calcul de la cle de controle / Calculation of the checksum For i% = 1 To Len(Code128$) dummy% = Asc(Mid$(Code128$, i%, 1)) dummy% = IIf(dummy% < 127, dummy% - 32, dummy% - 105) If i% = 1 Then checksum& = dummy% checksum& = (checksum& + (i% - 1) * dummy%) Mod 103 Next 'Calcul du code ASCII de la cle / Calculation of the checksum ASCII code checksum& = IIf(checksum& < 95, checksum& + 32, checksum& + 105) 'Ajout de la cle et du STOP / Add the checksum and the STOP Code128$ = Code128$ & Chr$(checksum&) & Chr$(211) End If End If Exit Function testnum: 'si les mini% caracteres a partir de i% sont numeriques, alors mini%=0 'if the mini% characters from i% are numeric, then mini%=0 mini% = mini% - 1 If i% + mini% <= Len(chaine$) Then Do While mini% >= 0 If Asc(Mid$(chaine$, i% + mini%, 1)) < 48 Or Asc(Mid$(chaine$, i% + mini%, 1)) > 57 Then Exit Do mini% = mini% - 1 Loop End If Return End Function |
Since the first publication of this page, I'd received numbered versions in different languages :
Language |
Author |
|
WinDev 5.5 |
Laurent PERICAUD |
|
L4G Progress |
Andre SEJOURNET |
|
Visual Foxpro |
Emile MAITREJEAN |
|
Delphi |
Jean-Camille POPULUS |
|
PL/SQL pour Oracle |
Nicolas FANCHAMPS |
|
Crystal Report |
Sebastien REZE |
|
Python |
Michel CLAVEAU |
|
Java |
Virginie LHUILLIER |
|
ASP |
G!L |
|
PHP |
Franck Odouard & |
|
C # |
Joffrey VERDIER |
The EAN.UCC 128 codes. These are codes 128 whose content is standardized and correspond to a use in the field of logistic. An EAN128 code starts with the Fnc1 character followed by one or several fields of data. Each field starts with an AI (Application Identifier) which announce the field content (Number of parcel or durability date for examples) followed by the data themselves. These datas are length fixed or variable, numerical or alphanumeric, with or without checksum and all this according to each AI. If a field is with variable length, that the maximum length isn't used and that it is not the last field, then it must be followed by a Fnc1 character. Some AI requires that the datas are followed by a checksum; this one is computed in the following way : The digits are numbered from right to left,
then we compute X the sum of even
digits and Y the sum of odd digits. I have written a small program allowing to create easily EAN128 codes and holding account of these characteristics. |
Do you like this
page ? Click here ! |