Table of Contents
Code 39 (also known as USS Code 39, Code 3 of 9) is the first
alpha-numeric symbology developed to be used in non-retail environment.
It is widely used to code alphanumeric information, such as the model number
etc. It is designed to encode 26 upper case letters A-Z
,
10 digits 0-9
and 7 special characters - hyphen (-), period (.),
dollar sign ($), forward slash (/), plus sign (+), percent (%) as well as the
space character.
Note
In version 1.5, to print a barcode character that will be scanned
as space, use underscore (_
) or equal
sign (=
). To print a blank white space, use space
character (ASCII 32
).
Although you can put as many characters as you can, in practice you can not encode many characters. Many barcode scanners have a short scan range at 3 inches.
Each Code 39 barcode must begin and end with special bar/space patterns.
They are often referred as start/stop character. In the font,
the start/stop character is mapped to the asterisk (*). You can also use
left square bracket [
and right square bracket ]
to produce them.
Creating a Code39 barcode is a simple task. Just enclose your data with asterisks and print the whole string with a C39 font, you get a barcode. For example, let's say that the data to be encoded is:
PN99018
The barcode string for printing as a Code39 barcode would be:
*P99018*
The below escape sequences print the barcode, and the human readable text below the barcode:
(0Y<ESC>(s0p8h12*PN99018* <ESC>(3@PN99018
C Code
The following code snippet demonstrates the barcode printing in C language.
int PrintPartNumberBarcode(char* pPartNo, FILE* prn) { /*select MRV Code39MA Height 12 points) */ fprintf(prn, "\x1B(0Y\x1B(s12.00H"); fprintf(prn, "*%s\n", pPartNo); }
BASIC Code
The following BASIC function returns the same barcode string.
Function GetBarcodeString(partno as string) as String Dim str as string str = "*" & partno & "*" GetBarcodeString=str End Function
Some applications, such as HIBC and LOGMARS, require a modulo 43 Check character at the end of the barcode (just before the stop character). The scanners must be configured with the checksum verification turned on in order to use the feature. The design of the checksum is to guard the data integrity. The scanner calculates the checksum at the time of scan, if it does not match the one in the barcode, the scanner assumes that some portion of the barcode was misprinted or misread and rejects the barcode.
Table 5.1. Code39 value table
char | value | char | value | char | value | char | value |
---|---|---|---|---|---|---|---|
0 | 0 | A | 10 | N | 23 | hyphen (-) | 36 |
1 | 1 | B | 11 | O | 24 | period (.) | 37 |
2 | 2 | C | 12 | P | 25 | SPACE ( ) | 38 |
3 | 3 | D | 13 | Q | 26 | dollar ($) | 39 |
4 | 4 | E | 14 | R | 27 | slash (/) | 40 |
5 | 5 | F | 15 | S | 28 | plus (+) | 41 |
6 | 6 | G | 16 | T | 29 | percent (%) | 42 |
7 | 7 | H | 17 | U | 30 | ||
8 | 8 | I | 18 | V | 31 | ||
9 | 9 | J | 19 | W | 32 | ||
K | 20 | X | 33 | ||||
L | 21 | Y | 34 | ||||
M | 22 | Z | 35 |
The following procedure explains how to calculate the modulo 43 checksum:
First assign each character in the barcode a numeric value (0 through 42) according to Table 5.1, “Code39 value table”. The start and stop characters do not participate the checksum calculation.
Sum the values of all the data characters.
Divide the result from step 2 by 43.
The remainder from the division in step 3 is the checksum character that will be appended to the data message before the stop character
Code39 standard also specifies a way to print characters outside the native Code 39 character set. It does so by encoding these characters with two native Code 39 characters. Four characters, the percent sign (%), dollar ($), slash (/) and plus sign (+) are used as leading characters.
Since these leading characters are also in the native Code 39 character set,
the barcode reader is unable to determine whether a barcode is Code 39 extended
or just normal code 39. For example, a barcode reader may read the extended
code 39 barcode abc
as +A+B+C
.
Fortunately, most scanners allow you configure if you expect a Code 39 extended
symbol (sometimes called Code 39 Full ASCII), or just a normal code 39 symbol.
When you need to encode characters outside the native set, use the table below.
For example, the sequence for lower case letter a
is +A
.
ASCII | Encoding | ASCII | Encoding | ASCII | Encoding | ASCII | Encoding |
---|---|---|---|---|---|---|---|
NUL | %U | Space | = or - | @ | %V | ` | %W |
SOH | $A | ! | /A | A | A | a | +A |
STX | $B | " | /B | B | B | b | +B |
ETX | $C | # | /C | C | C | c | +C |
EOT | $D | $ | /D | D | D | d | +D |
ENQ | $E | % | /E | E | E | e | +E |
ACK | $F | & | /F | F | F | f | +F |
BEL | $G | ' | /G | G | G | g | +G |
BS | $H | ( | /H | H | H | H | H |
HT | $I | ) | /I | I | I | i | +I |
LF | $J | * | /J | J | J | j | +J |
VT | $K | + | /K | K | K | k | +K |
FF | $L | , | /L | L | L | l | +L |
CR | $M | - | - | M | M | m | +M |
SO | $N | . | . | N | N | n | +N |
SI | $O | / | /O | O | O | o | +O |
DLE | $P | 0 | 0 | P | P | p | +P |
DC1 | $Q | 1 | 1 | Q | Q | q | +Q |
DC2 | $R | 2 | 2 | R | R | r | +R |
DC3 | $S | 3 | 3 | S | S | s | +S |
DC4 | $T | 4 | 4 | T | T | t | +T |
NAK | $U | 5 | 5 | U | U | u | +U |
SYN | $V | 6 | 6 | V | V | v | +V |
ETB | $W | 7 | 7 | W | W | w | +W |
CAN | $X | 8 | 8 | X | X | x | +X |
EM | $Y | 9 | 9 | Y | Y | y | +Y |
SUB | $Z | : | /Z | Z | Z | z | +Z |
ESC | %A | ; | %F | [ | %K | { | %P |
FS | %B | > | %G | \ | %L | | | %Q |
GS | %C | = | %H | ] | %M | } | %R |
RS | %D | < | %I | ^ | %N | ~ | %S |
YS | %E | ? | %J | _ | %O | DEL | %T, %X, %Y, %Z |
UPC-A is widely used in the United States and Canada to identify retail products at the time of checkout. A UPC-A symbol has a fixed length of 12 digits, with the last digit served as a checksum. The first digit is called “number system”, followed by the manufacturer code and product code. The Uniform Code Council has the authority assigning manufacturer code. The remaining digits, the product code, is assigned by the manufacturer. This arrangement ensures that every retail proudct has its unqiue identification number.
The UPC-A encoding scheme is relativley complicated. A digit has two different encodings depending on the position of the digit. A complete barcode string contains 15 characters, divided into 7 parts: [3]
Character Index | Pattern |
---|---|
1 | Left Guard |
2-7 | 6-digit left halve |
8 | Center Guard |
9-14 | 6-digit right halve |
15 | Right Guard |
The left guard and right guard have the same encoding patterns.
They can be printed using asterisk, left and right parenthesis or brackets: *
, (
and )
, or [
and ]
. The center guard can be
printed using either a vertical bar symbol |
or the
hyphen -
.
The patterns for the left halve digits are represented by 0-9 respectively; and the right halve digits are mapped to A-J:
Digit | Left Halve | Right Halve |
---|---|---|
0 | 0 | A |
1 | 1 | B |
2 | 2 | C |
3 | 3 | D |
4 | 4 | E |
5 | 5 | F |
6 | 6 | G |
7 | 7 | H |
8 | 8 | I |
9 | 9 | J |
For example, suppose we wish to encode the number 543000186706
. The following three lines produce identical
barcodes:
*543000|BIGHAG* (543000-BIGHAG) [543000|BIGHAG]
A UPC-A data consists of 12 digits in total. The last digit is derived from the previous 11 digigts based on modulo 10 algorithm [4]. To calucalte the check digit, follow the steps below:
From the right to left, start with odd position, assign the odd/even position to each digit.
Sum all digits in odd position and multiply the result by 3.
Sum all digits in even position.
Sum the results of step 3 and step 4.
Divide the result of step 4 by 10. The check digit is the number which adds the remainder to 10.
For example, assume that we want to calculate the check digit of UPC-A
number 72641217542
.
Procedure 5.1. Calculating check digit for UPC-A number 72641217542
Step 1
Arrange a two-row matrix, labelled from 1 to 11, with 1 being the leftmost position. Copy each digit into the matrix.
From the right to the left, start with odd position, assign the odd/even position to each digit.
Index 1 2 3 4 5 6 7 8 9 10 11 Digit 7 2 6 4 1 2 1 7 5 4 2 Position O E O E O E O E O E O Step 2
Sum all digits in odd position, and multiply the result by 3.
7 + 6 + 1 + 1 + 5 + 7 + 2 = 22 22 X 3 = 66
Step 3
Sum all digits in even position.
2 + 4 + 2 + 7 + 4 = 19
Step 4
Sum the results of step 3 and 4.
66 + 19 = 85
Step 5
Divide the result of step 4 by 10. The check digit is the number which adds the remainder to 10. In this example, divide 85 by 10 results in remainder 5. Thus, 5 is the check digit since it results in 10 when added to 5.
Append the check digit to the data we get the full UPC-A code:
726412175425
.
Refer to the code in the following section for a sample implementation.
C Code
The following C code illustrates the check digit calculation and the barcode string generation.
static char barcode_string[20]; int upc_a_check_digit(char* data) { int sum, check_digit; char* p; sum=0; sum = (data[0]+data[2]+data[4]+data[6]+data[8]+data[10])*3 + (data[1]+data[3]+data[5]+data[7]+data[9]+data[11]); check_digit = 10-(sum %10 ); if (check_digit==10 ) check_digit=0; return check_digit; } char* upc_barcode_string(char* data) { char* p; int i; int check_digit; memset(barcode_string, 0, sizeof(barcode_string)); check_digit=upc_a_check_digit(data); barcode_string[0]='['; for(i=0; i<6; i++) barcode_string[i+1]=data[i]; barcode_string[7]='|'; for(i=6; i<10; i++) barcode_string[i+2]=data[i]-'0'+'A'; barcode_string[13]=check_digit +'A'; barcode_string[14]=']'; return barcode_string; }
BASIC Code
Function upc_a_check_digit(data as String) As Integer Dim sum as Integer Dim i As Integer sum=0 for i=1 to 11 Step 2 sum = sum + Val(Mid(data,I,1)) Next i sum = sum * 3 For i=2 to 11 Step 2 sum=sum+Val(Mid(data, I, 1)) Next i sum = 10 - (10 Mod 10) if ( sum=10 ) Then sum=0 End IF upc_a_check_digit=sum; End Function Function upc_barcode_string(data as String) As String Dim check_digit As Integer Dim I As Integer Dim barcode_string As String Dim myChar as Integer barcode_string="[" barcode_string = barcode_string & Left$(data, 6) & "|" for i=7 to 11 myChar = Val(Mid(data,I,1)) myChar = myChar + Asc("A") barcode_string=barcode_string & chr(myChar) Next i myChar = upc_a_check_digit(data) barcode_string = barcode_string & chr(myChar) & "]" upc_barcode_string=barcode_string End Function
The POSTNET (POSTal Numeric Encoding Technique) bar code type was developed by the U. S. Post Office to encode a delivery address, which can be one of three forms (1) 5-digit ZIP; (2) 5-digit ZIP+4 code and (3) 11-digit delivery point code. A valid POSTNET barcode comprises either 32 bars, 52 bars or 62 bars (including frame bars and check digit, see below).
POSTNET is a numeric symbology. Different from other symbologies, POSTNET is a height-modulated symbology which encodes the data in the height of the barcode instead of the width.
A POSTNET barcode consists of a starting frame bar, data digits, a check digit and a stopping frame bar, as illustrated above. Therefore, simplying formating the number with the font won't produce a valid barcode.
You can use either the asterisk *
, vertical bar
symobl |
, left or right
square brackets [
and ]
for the
starting and ending frame bar. So if you know the check digit is 1
for zip code 91801
, you can enter [918011]
and
format it with the font mrvpostnet.sfp
. To learn how to calculate the check digit,
scroll down to the next section.
The value of the check digit is that when added to the sum
of other digits in the barcode, results in a total that is multiple
of 10. For our sample zip code 91801
, the check digit
is 1
since 9+1+8+0+1+1=20
which is two times of 10
.
C Code
char zipcode[20], barcodestring[20]; char* p; int sum, check_digit; strcpy(zipcode, "918011234"); sum=0; p=zipcode; while (*p!=NULL) { sum += *p-'0'; p++; } check_digit = 10 - (sum%10); if (check_digit==10 ) check_digit=0; printf("*%s%d*", zipcode, check_digit);
BASIC Code
Dim i As Integer Dim charToEncode As String Dim checkSum As Integer Dim checkDigit As String Dim strZipCode As String strZipCode = "918011234"; For i = 1 To Len(inpara) charToEncode = Mid(strZipCode, i, 1) Postnet = Postnet + charToEncode checkSum = checkSum + Val(charToEncode) Next i checkSum = checkSum Mod 10 If checkSum <> 0 Then checkSum = 10 - checkSum checkDigit = Chr(checkSum + Asc("0"))
Included in this Morovia PCL Bar codes & More package are the PCL
bitmap fonts for printing OCR-A and OCR-B characters. The mrvocra.sfp
prints OCR-A size I characters while mrvocrb.sfp
for
OCR-B size I characters. Both fonts have a point size of 12 and
a fixed pitch of 10 cpi (Character per inch).
For other OCR character sizes, see http://www.morovia.com/font/ocr.asp.
[3] The character mapping of Morovia PCL Bar codes & more is based on the original HP package. This package does not encode EAN-13. There is no human readable either. If you want to produce regular EAN-13 or UPC-A barcodes with human readable, check Morovia UPC/EAN/Bookland Fontware product.
[4] A web utility to calculate UPC-A check digit is located at http://www.morovia.com/education/utility/upc-ean.asp.