Structure Of A Code 128 Barcode
A Code 128 bar code consists of a leading quiet zone, one of three start codes, the data itself, a check character,
a stop character, and a trailing quiet zone.
The start code that is used determines which character set will be used. The character set may also be
changed in the middle of the bar code. The switch code changes the subset for the next character only.
To create a more compact NDC, character set "C" is used because of it's double density. For an 11-digit NDC,
start with character set "C" for the first 10 digits, then switch to subset "B" for the final digit.
To encode a value as a Code 128 bar code, the checksum digit must first be calculated (see procedure below)
and the entire bar code, including check digit, may then be encoded as a sequence of bars and spaces.
A Code 128 bar code for an 11-digit NDC has the following physical structure:
- Leading quiet zone.
- Start code C, which is the code 105 from the encoding table below.
- Each of the data bytes of the first 5 pairs of digits.
- Switch code B, which is the code 100 from the encoding table below.
- The last single digit.
- The checksum byte, calculated as below and encoded using the table below.
- Stop character.
- Termination bar.
- Trailing quiet zone.
An example of a Code 128 bar code for Fosinopril 10mg, NDC 00185-0041-09:
Computing The Checksum Digit
Before a Code 128 symbol may be encoded, the checksum digit to be included in the barcode must be calculated.
The checksum digit is based on a modulo 103 calculation based on the weighted sum of the values of each of
the digits in the message that is being encoded, including the start character.
The steps for calculating the check digit are as follows:
- Take the value of the start subset C character (105) and make that the starting value of the running checksum.
- Starting with the first data character following the start character, take the value of the character (between 0
and 99, inclusive) multiply it by its character position (1) and add that to the running checksum.
- Take each additional character in the message, take its value, and multiply it by its character position, and add
the total to the running checksum.
- If a Switch code is used, the value of the switch code is multiplied by its character position and added to the running checksum.
- Divide the resulting running checksum by 103. The remainder becomes the checksum digit which is added to the
end of the message.
- The stop character is appended after the checksum digit.
This is easier to understand with an example. Let's calculate the checksum digit for the sample bar code
above, Fosinopril 10mg, NDC "00185-0041-09".
Barcode |
START-C |
00 |
18 |
50 |
04 |
10 |
SWITCH-B |
9 |
Character Value |
105 |
00 |
18 |
50 |
04 |
10 |
100 |
25 value for set B is number + 16 |
Character Position |
- |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Calculation |
105 |
00 x 1 |
18 x 2 |
50 x 3 |
04 x 4 |
10 x 5 |
100 x 6 |
25 * 7 |
Weighted Sum |
105 |
0 |
36 |
150 |
16 |
50 |
600 |
175 |
Running sum |
105 |
105 |
141 |
291 |
307 |
350 |
957 |
1132 |
Summing up the running checksum for each digit, we get 1132. This value divided by 103 is 1132 / 103 = 10
with a remainder of 102. Thus the checksum digit is the character which has a value of 102.
NOTE: The checksum starts with the Start Character, with a weight of 1, and that the first data character also has a weight of 1.
NOTE: For checksums less than 10, the character should be padded with a zero, and encoded with the appropriate code from subset C.
Encoding The Symbol
Once the checksum digit has been calculated we know the entire message which must be encoded in the bars and
spaces. Continuing with our example, we will encode, from zero, the Code 128 bar code we used in our example above:
00185004109 with a checksum digit of 102.
The encoding table at the bottom of this page indicates how to encode each digit of a Code 128 barcode.
The number "1" represents a "dark" or "bar" section of the bar code whereas a "0" represents a "light" or
"space" section of the bar code. Thus the numbers 1101 represents a double-wide bar (11), followed by a
single-wide space (0), followed by a single-wide bar (1). This would be printed in the bar code as:
Code 128 Encoding Example
We will now code the above NDC example, 00185-0041-09, in Code 128. As we calculated in the Checksum
Digit Calculation section, the checksum digit is 102. So we must also code the checksum digit at the
end of the message.
We encode each digit using the encoding table below.
- The START-C character: 11010011100.
- The digit "00" encoded as: 11011001100.
- The digit "18" encoded as: 11001110010.
- The digit "50" encoded as: 11000101110.
- The digit "04" encoded as: 10010001100.
- The digit "10" encoded as: 11001000100.
- The SWITCH-B character: 10111101110.
- The digit "9" encoded as: 11100101100.
- The checksum digit of 102 encoded as: 11110101110.
- The STOP character: 11000111010.
- The termination bar: 11.
This is shown in the following graphical representation where the bar code has been sectioned-off into areas
that reflect each of the 11 components described above.
Code 128 Encoding Table
This table indicates how to encode each digit of a Code 128 bar code. Note that it is easiest to think of each
character as a value between 0 and 105, inclusive, rather than thinking of them as characters. The character that
a value represents depends on what mode (or character set) you're in-so rather than thinking of a character as "A" or
"B", etc. it is more appropriate to think of it as 33, 34, etc.
VALUE |
WHICH REPRESENTS IN CHARACTER SET |
ENCODING |
VALUE |
WHICH REPRESENTS IN CHARACTER SET |
ENCODING |
A |
B |
C |
A |
B |
C |
00 |
SP |
SP |
00 |
11011001100 |
53 |
U |
U |
53 |
11011101110 |
01 |
! |
! |
01 |
11001101100 |
54 |
V |
V |
54 |
11101011000 |
02 |
" |
" |
02 |
11001100110 |
55 |
W |
W |
55 |
11101000110 |
03 |
# |
# |
03 |
10010011000 |
56 |
X |
X |
56 |
11100010110 |
04 |
$ |
$ |
04 |
10010001100 |
57 |
Y |
Y |
57 |
11101101000 |
05 |
% |
% |
05 |
10001001100 |
58 |
Z |
Z |
58 |
11101100010 |
06 |
& |
& |
06 |
10011001000 |
59 |
[ |
[ |
59 |
11100011010 |
07 |
' |
' |
07 |
10011000100 |
60 |
\ |
\ |
60 |
11101111010 |
08 |
( |
( |
08 |
10001100100 |
61 |
] |
] |
61 |
11001000010 |
09 |
) |
) |
09 |
11001001000 |
62 |
^ |
^ |
62 |
11110001010 |
10 |
* |
* |
10 |
11001000100 |
63 |
_ |
_ |
63 |
10100110000 |
11 |
+ |
+ |
11 |
11000100100 |
64 |
NUL |
` |
64 |
10100001100 |
12 |
, |
, |
12 |
10110011100 |
65 |
SOH |
a |
65 |
10010110000 |
13 |
- |
- |
13 |
10011011100 |
66 |
STX |
b |
66 |
10010000110 |
14 |
. |
. |
14 |
10011001110 |
67 |
ETX |
c |
67 |
10000101100 |
15 |
/ |
/ |
15 |
10111001100 |
68 |
EOT |
d |
68 |
10000100110 |
16 |
0 |
0 |
16 |
10011101100 |
69 |
ENQ |
e |
69 |
10110010000 |
17 |
1 |
1 |
17 |
10011100110 |
70 |
ACK |
f |
70 |
10110000100 |
18 |
2 |
2 |
18 |
11001110010 |
71 |
BEL |
g |
71 |
10011010000 |
19 |
3 |
3 |
19 |
11001011100 |
72 |
BS |
h |
72 |
10011000010 |
20 |
4 |
4 |
20 |
11001001110 |
73 |
HT |
i |
73 |
10000110100 |
21 |
5 |
5 |
21 |
11011100100 |
74 |
LF |
j |
74 |
10000110010 |
22 |
6 |
6 |
22 |
11001110100 |
75 |
VT |
k |
75 |
11000010010 |
23 |
7 |
7 |
23 |
11101101110 |
76 |
FF |
l |
76 |
11001010000 |
24 |
8 |
8 |
24 |
11101001100 |
77 |
CR |
m |
77 |
11110111010 |
25 |
9 |
9 |
25 |
11100101100 |
78 |
SO |
n |
78 |
11000010100 |
26 |
: |
: |
26 |
11100100110 |
79 |
SI |
o |
79 |
10001111010 |
27 |
; |
; |
27 |
11101100100 |
80 |
DLE |
p |
80 |
10100111100 |
28 |
< |
< |
28 |
11100110100 |
81 |
DC1 |
q |
81 |
10010111100 |
29 |
= |
= |
29 |
11100110010 |
82 |
DC2 |
r |
82 |
10010011110 |
30 |
> |
> |
30 |
11011011000 |
83 |
DC3 |
s |
83 |
10111100100 |
31 |
? |
? |
31 |
11011000110 |
84 |
DC4 |
t |
84 |
10011110100 |
32 |
@ |
@ |
32 |
11000110110 |
85 |
NAK |
u |
85 |
10011110010 |
33 |
A |
A |
33 |
10100011000 |
86 |
SYN |
v |
86 |
11110100100 |
34 |
B |
B |
34 |
10001011000 |
87 |
ETB |
w |
87 |
11110010100 |
35 |
C |
C |
35 |
10001000110 |
88 |
CAN |
x |
88 |
11110010010 |
36 |
D |
D |
36 |
10110001000 |
89 |
EM |
y |
89 |
11011011110 |
37 |
E |
E |
37 |
10001101000 |
90 |
SUB |
z |
90 |
11011110110 |
38 |
F |
F |
38 |
10001100010 |
91 |
ESC |
{ |
91 |
11110110110 |
39 |
G |
G |
39 |
11010001000 |
92 |
FS |
| |
92 |
10101111000 |
40 |
H |
H |
40 |
11000101000 |
93 |
GS |
} |
93 |
10100011110 |
41 |
I |
I |
41 |
11000100010 |
94 |
RS |
~ |
94 |
10001011110 |
42 |
J |
J |
42 |
10110111000 |
95 |
US |
DEL |
95 |
10111101000 |
43 |
K |
K |
43 |
10110001110 |
96 |
FNC3 |
FNC3 |
96 |
10111100010 |
44 |
L |
L |
44 |
10001101110 |
97 |
FNC2 |
FNC2 |
97 |
11110101000 |
45 |
M |
M |
45 |
10111011000 |
98 |
SHIFT |
SHIFT |
98 |
11110100010 |
46 |
N |
N |
46 |
10111000110 |
99 |
Code C |
Code C |
99 |
10111011110 |
47 |
O |
O |
47 |
10001110110 |
100 |
Code B |
FNC4 |
Code B |
10111101110 |
48 |
P |
P |
48 |
11101110110 |
101 |
FNC4 |
Code A |
Code A |
11101011110 |
49 |
Q |
Q |
49 |
11010001110 |
102 |
FNC1 |
FNC1 |
FNC1 |
11110101110 |
50 |
R |
R |
50 |
11000101110 |
103 |
START A |
START A |
START A |
11010000100 |
51 |
S |
S |
51 |
11011101000 |
104 |
START B |
START B |
START B |
11010010000 |
52 |
T |
T |
52 |
11011100010 |
105 |
START C |
START C |
START C |
11010011100 |
|
  |
STOP |
STOP |
STOP |
11000111010 |
References and recommended reading
- Palmer, Roger C. The Bar Code Book, Third Edition. Peterborough, NH: Helmers Publishing, 1995.
- U.S. Food and Drug Administration National Drug Code Directory. Page Last Updated: 11/30/2009.