Chapter 5. Barcode Technologies

5.1. Code 3 of 9

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

5.1.1. Modulo 43 Checksum

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

charvaluecharvaluecharvaluecharvalue
00A10N23hyphen (-)36
11B11O24period (.)37
22C12P25SPACE ( )38
33D13Q26dollar ($)39
44E14R27slash (/)40
55F15S28plus (+)41
66G16T29percent (%)42
77H17U30  
88I18V31  
99J19W32  
  K20X33  
  L21Y34  
  M22Z35  

The following procedure explains how to calculate the modulo 43 checksum:

  1. 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.

  2. Sum the values of all the data characters.

  3. Divide the result from step 2 by 43.

  4. The remainder from the division in step 3 is the checksum character that will be appended to the data message before the stop character

5.2. Code 39 Extended

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.

ASCIIEncodingASCIIEncodingASCIIEncodingASCIIEncoding
NUL%USpace= or -@%V`%W
SOH$A!/AAAa+A
STX$B"/BBBb+B
ETX$C#/CCCc+C
EOT$D$/DDDd+D
ENQ$E%/EEEe+E
ACK$F&/FFFf+F
BEL$G'/GGGg+G
BS$H(/HHHHH
HT$I)/IIIi+I
LF$J*/JJJj+J
VT$K+/KKKk+K
FF$L,/LLLl+L
CR$M--MMm+M
SO$N..NNn+N
SI$O//OOOo+O
DLE$P00PPp+P
DC1$Q11QQq+Q
DC2$R22RRr+R
DC3$S33SSs+S
DC4$T44TTt+T
NAK$U55UUu+U
SYN$V66VVv+V
ETB$W77WWw+W
CAN$X88XXx+X
EM$Y99YYy+Y
SUB$Z:/ZZZz+Z
ESC%A;%F[%K{%P
FS%B>%G\%L|%Q
GS%C=%H]%M}%R
RS%D<%I^%N~%S
YS%E?%J_%ODEL%T, %X, %Y, %Z

5.3. UPC-A

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 IndexPattern
1Left Guard
2-76-digit left halve
8Center Guard
9-146-digit right halve
15Right 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:

DigitLeft HalveRight Halve
00A
11B
22C
33D
44E
55F
66G
77H
88I
99J

For example, suppose we wish to encode the number 543000186706. The following three lines produce identical barcodes:

    *543000|BIGHAG*
    (543000-BIGHAG)
    [543000|BIGHAG] 

5.3.1. Calculate UPC-A Check Digit

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:

  1. From the right to left, start with odd position, assign the odd/even position to each digit.

  2. Sum all digits in odd position and multiply the result by 3.

  3. Sum all digits in even position.

  4. Sum the results of step 3 and step 4.

  5. 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

  1. 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.

    Index1234567891011
    Digit72641217542
    PositionOEOEOEOEOEO
  2. 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 
  3. Step 3

    Sum all digits in even position.

    2 + 4 + 2 + 7 + 4 = 19 
  4. Step 4

    Sum the results of step 3 and 4.

    66 + 19 = 85  
  5. 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 

5.4. POSTNET

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.

Figure 5.1. POSTNET barcode structure

POSTNET barcode structure

5.4.1. Barcode Structure

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.

5.4.2. Check Digit Calulation

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"))

5.5. OCR-A & OCR-B

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).

Figure 5.2. OCR-A characters

OCR-A characters

Figure 5.3. OCR-B characters

OCR-B characters

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.

Do you know?

This manual is specific to PCL Barcodes & More 1.5.
The current version is 1.5.0.

This Manual is also available in the following format: PDF.