12,243,721 members (43,793 online)
alternative version

76.3K views
17 bookmarked
Posted

# The Asti Spumante Bar Code

, 3 Jun 2008 CPOL
 Rate this:
An interesting article to learn how UPC-A bar coding works

## Introduction

I've decided to write this article after reading the novel 'THE ASTI SPUMANTE CODE' by Toby Clements, which is a parody of 'THE DA VINCI CODE' by Dan Brown. I'm not that obsessed with any of these books, but just thought it would be more interesting to introduce UPC-A barcoding from such a perspective; though sarcastic.

Almost every item we buy or own has a barcode printed on it. We see those barcodes every day, but still we don't understand what they really mean or how to generate them. The major benefit of using barcodes is to automate and improve the speed and accuracy of data collection. That's why we see them on most sellable items.

One other way to look at barcodes is to think of them as one other form of cryptography that's so easy to decipher using barcode scanners. For example, a UPC-A barcode is a simple encoding of a 12 digit number into its bit representation, where 1 is represented as black vertical line and 0 represented as white vertical line. We will be creating a Java program that just does that.

Note: Image Cropped From 'THE ASTI SPUMANTE CODE' Book Cover

## Background

In 'The Da Vinci Code', the secret that Robert Langdon and Sophie were searching for was the Holy Grail, which the Priory of Sion has hidden for centuries. However, in 'The ASTI SPUMANTE CODE', the secret that James Crack and Emily were searching for was the greatest book that will ever be written. According to Toby Clements, 'the secret ingredients of this book - characterization, plot, setting, and so forth - what para-literalists call the Asti Spumante Code - are contained on something called the Mure-de-Paume, the legendary keystone.'

While searching for the code, James Crack and Emily find a prolix, or simply what I concluded, a book. They discover under the book's red leather cover 'a rectangle of paper approximately five centimeters by three, laminated to the back of the prolix. On the piece of paper were a set of lines of differing widths and heights that could be read from right to left, or left to right, or not at all. It was a code. A barcode.' As sarcastic as this can get, it does describe what a barcode looks like.

In order to be able to read the barcode, James Crack escapes to London to a bookstore owned by Donnie Dogs. Clark asks Dogs about barcodes, and Dogs explains that barcodes are named by scholars as UPC, or Universal Product Code. Manufactures buy those barcodes from UCC, or Uniform Code Council. The UPC is made up of exactly 12 digits. Each digit is represented as a stream of 7 bits, and each bit corresponds to a slice (1 for black slices and 0 for white ones). The first 6 digits for the 12-digit UPC correspond to the manufacturer code, and they are handed down by UCC. The next 5 digits correspond to the product code, and they are filled by the manufacturer. The last digit is a check digit used to help the barcode scanner make sure that it read the right code number. And as we've all seen, in a bookstore or super market, a scanner reads the barcode through red laser beams (i.e. barcode reader). In 'The ASTI SPUMANTE CODE', it is this check digit that James and Emily have to calculate in order to reach the hidden secret. Wow, what an impossible mission!

The check digit is calculated by first adding the odd-spaced digits (6 characters), multiplying them by three, then adding them to the sum of the even-spaced digits (5 characters since we exclude the check digit). Then subtract from the next higher multiple of 10.

For example, let's say we want to find the check digit for the following code: 31415926535.

```3 * (3 + 4 + 5 + 2 + 5 + 5) + (1 + 1 + 9 + 6 + 3) = 3 * (24) + (20) = 92
==> Check code = 100 - 92 = 8.```

## Overview

There are many kinds of barcodes:

• Codabar
• Code 128
• Code 3 of 9
• Code 93
• EAN 13
• EAN 8
• Interleabed 2/5
• MSI/Plessey
• Postal/Postnet
• UPC-A
• UPC-E

The kind that Toby Clements refers to in his parody is UPC-A. In the UPC code, only the digits [0-9] are allowed. However, in other types of barcoding, you might have characters, symbols, or even images!

## UPC-A

In addition to the information that Dogs mentioned, there remains some useful information that we need to know about the UPC-A barcode.

### Structure of UPC-A Barcode

We can divide the 12 digit UPC code into two parts: the left 6 digits and the right 6 digits. Every digit has its predefined stream of bits based on whether it is a left or a right digit.

 Digit Bits for Left Digits Bits for Right Digits 0 0001101 1110010 1 0011001 1100110 2 0010011 1101100 3 0111101 1000010 4 0100011 1011100 5 0110001 1001110 6 0101111 1010000 7 0111011 1000100 8 0110111 1001000 9 0001011 1110100

For example, the left 3 in the following code 314159265358 would be converted into 0111101, while the right 3 would be converted into 1000010.

The left, middle, and right codes are used to help the scanner (or reader) identify where the code starts and ends. The number system is a single digit which identifies the type of the product.

 Number System Description 0 Regular UPC codes 1 Reserved 2 Weight items marked at the store 3 National Drug/Health-related code 4 Non-Food items 5 Coupons 6 Reserved 7 Regular UPC codes 8 Reserved 9 Reserved

The remaining digits should be well known by now, as explained by Dogs and as shown in the figure.

## The Program

This program converts a 12 digit code into a barcode. The whole idea is very simple: read a digit, convert it to its corresponding 7 bits based on whether it is on the left or the right, and then draw a vertical line for every 1, and skipping space for every 0. The program also includes a feature to let you calculate the check digit. In case you have entered a wrong check digit, the program doesn't display a barcode.

### Program View

UPC is the number entered by the user, and barcode is the alternating black and white lines (or slices) that we want to generate.

### How To Run The Program

I have used BlueJ as the environment to implement this program. So if you have BlueJ, you can easily open it, view the UML diagram, and run the `Main `class. Otherwise, you can always run the *.jar file or execute the Run.bat file.

### Using the Code

As shown in the figure above, the `Main `class uses the `ASBarcode `class, which is the major class that contains all the program's logic. The `ASBarcode `uses the `UPCField `and `BarcodeLabel `classes. The `UPCField `class inherits from the `MNDigitField `class, which represents a text field that allows only digits and up to maximum of `N `digits. This class also has two component actors (`MComponentActor `and `NComponentActor`) which act on two components (`MComponent `and `NComponent`). In our case, the `MComponent `is the 'Generate Check Digit' button, the `NComponent `is the 'Generate Barcode' button, and the action that the `MComponentActor `and `NComponentActor `do is enable or disable the buttons.

### GUI Behavior

We have a panel (`ASBarcode`) containing a text field (`UPCField`) where the user can enter UPC-A code, a barcode label (`BarcodeLabel`) generated when the user clicks "Generate Bar Code" button, a label ("Enter UPC"), and two buttons ("Generate check Digit" and "Generate bar Code"). The two buttons are initially disabled. Once the user types 11 characters in the UPC-A field (`UPCField`), the "Generate Check Digit" button becomes enabled. The user will then click this button, and the check digit will be generated. As a result, the UPC field will now contain 12 characters, and thus the "Generate Check Digit" buttons gets disabled and the "Generate Bar Code" button gets enabled. Now, the user would click on the "Generate Bar Code" button, and the barcode will be generated based on the UPC-A code specified in the UPC field. However, before generating the barcode label, the program checks if the UPC-A code entered by the user is valid (UPC-A is valid if it is a 12 digit number and the value of the check digit is valid). In case the UPC-A code is invalid, nothing is displayed on the barcode label.

### Class Deign

#### ASBarcode

• The `codeProjectOrange `variable represents the orange color used at The Code Project, whose RGB components are Red = 255, Green = 153, and Blue = 0.
• The `barcodeLabel `is a reference to the `BarcodeLabel `object that will display the generated barcode.
• The `barcodePanel `is the panel that will hold the `BarcodeLabel `component.
• The two variables `generateCheckDigitButton `and `generateBarcodeButton `are references to `JButton `objects, and will both fire an `ActionEvent `when the user clicks them. The `CheckDigitListener `and `BarcodeListener `classes will handle those events.
• The `buttonPanel `is a panel that will hold the two buttons.
• The `upcField `is a reference to the field where the user enters the UPC code.
• The `upcPanel `is the panel that will hold this field.

The logic of the program is found in the `ASBarcode() `constructor, and the main method is used to test the `ASBarcode `class.

##### Initialization
• Create the Barcode Label with a slice width of 2 pixels and a slice height of 150 pixels. Let the color of slices (1) be black and of empty space (0) be orange. In case there is any other number (other than 0 or 1), then draw the red color to reflect that something went wrong. Add the barcode label to its panel.

```barcodeLabel = new BarcodeLabel
(2, 150, Color.black, codeProjectOrange, Color.red);```
• Create the 'Generate Check Digit' and 'Generate Bar Code' and add them to their panel. Also, add action listeners (`CheckDigitListener `and `BarcodeListener`) to them, and make them initially disabled.
• Create the UPC field and pass to it as arguments the `generateCheckDigitButton `and `generateBarcodeButton `buttons. Those will be the components on which the `MComponentActor `and `NComponentActor `will act on. Don't get confused, this will be explained in more details under the `UPCField `and `MNDigitField `classes.
• At last, add all those components to the `ASBarcode `panel.

#### CheckDigitListener

The method below is called when the 'Generate Check Digit' button is clicked.

```void actionPerformed (ActionEvent e)
{
// Generate the check digit and append it at the end of the 11-digit UPC field
upcField.generateCheckDigit ();
}```

#### BarcodeListener

The method below is called when the 'Generate Bar Code' button is clicked. If the check digit is valid, the barcode is generated and displayed.

```public void actionPerformed (ActionEvent e)
{
// Generate the barcode only if the check digit is valid
if (upcField.isCheckDigitValid ())
{
// Set the UPC of the barcode label
barcodeLabel.setUPC (upcField.getUPC());

// Validate the UPC of the barcode label
barcodeLabel.validateUPC ();

// Generate the barcode
barcodeLabel.generateBarcode ();

// Select the text in the UPC field
upcField.selectAll ();
}
else
{
// Make the barcode as invalid so that nothing would be drawn on
// the barcode panel.
// Check BarcodeLabel.paintComponent
barcodeLabel.setValid (false);
}
}```

#### BarcodeLabel

##### Constants

We first start by defining the constants:

```// Put in front and at end of every barcode
final String quiteZone = "000000000";

// Put after quite zone at the front - <a href=""%22#Structure"">See Figure</a>
final String leftStartCode = "101";

// Put before quite zone at the end - <a href=""%22#Structure"">See Figure</a>
final String rightEndCode = "101";

// Put in the center of every barcode - <a href=""%22#Structure"">See Figure</a>
final String centerCode = "01010";

// Represent the <a href=""%22#Bits"">left UPC bits</a> for the digits
final String leftCodes[] = {"0001101", "0011001", "0010011", "0111101",
"0100011", "0110001", "0101111", "0111011",
"0110111", "0001011"};

// Represent the <a href=""%22#Bits"">right UPC bits</a> for the digits
final String rightCodes[] = {"1110010", "1100110", "1101100", "1000010",
"1011100", "1001110", "1010000", "1000100",
"1001000", "1110100"};

// represents the number of slices in a UPC-A
final int sliceNum = 113; // 3 + 3 + 5 + (12 * 7) + (9 * 2) = 113```

The quite zone, left, center, and right codes will be added to every barcode we are going to generate.

We would care to know the number of slices we have in order to define the widths of the slices and of the panel that will hold them. The `sliceNum `is a constant equal to `113`. This is the sum of the left, center, right codes (3 + 5 + 3), the 12 digits, where each digit is made up of 7 slices or bits (12 * 7), and the quite zone (9 * 2).

##### Instance Variables
```String UPC;         // UPC to be converted into barcode
String barcode;     // the barcode
boolean valid;      // UPC is valid or not?
Color barColor;     // The color of the slice corresponding to bit 1
Color spaceColor;   // The color of the slice corresponding to bit 0
Color errorColor;   // In case the bit is neither 0 or 1 (something wrong)
int x;              // Represents the current x coordinate of the slice
int sliceWidth;     // Represents the width of the slice
int width;          // Width of barcode label
int height;         // height of barcode label
```
##### Methods

The constructor sets the color and size of the barcode label.

```//---------------------------------------------------------------------
//  Constructor...
//
//  sw is the slice width and sh is the slice height.
//  bc is the bar color, sc is the space color, and ec is error color.
//---------------------------------------------------------------------
public BarcodeLabel (int sw, int sh, Color bc, Color sc, Color ec)
{
//  Upc is initially invalid
valid = false;

//  Set x initially to zero
x = 0;

//  Set the slicewidth
sliceWidth = sw;

//  Set the width of barcode label
width = sliceNum * sw;

//  Set the height of barcode label
height = sh;

//  Set the colors
barColor = bc;
spaceColor = sc;
errorColor = ec;

//  Set the background color to space color
this.setBackground (spaceColor);

//  Set the preferred size of the barcode label
this.setPreferredSize (new Dimension (width, height));
}```

The `paintComponent() `method draws the barcode label by first clearing the background and then only drawing the slices if the UPC code is valid.

```//---------------------------------------------------------------------
//  Paints the barcode only if it is valid...
//---------------------------------------------------------------------
public void paintComponent (Graphics page)
{
super.paintComponent (page);

//  Clear the barcode before drawing
page.setColor (getBackground ());
page.fillRect (0, 0, width, height);

//  Draw the barcode only if the UPC is valid
if (isValid ())
drawBarcode (page);
}```

This method takes care of drawing the vertical slices over the label.

```//---------------------------------------------------------------------
//  Draws the barcode if it is not null.
//---------------------------------------------------------------------
public void drawBarcode (Graphics page)
{
int barcodeLength;

//  Set x to zero
x = 0;

if (barcode != null)
{
//  Get the barcode length
barcodeLength = barcode.length ();

//  Loop over every character (0 or 1)
for (int i = 0; i < barcodeLength; i++)
{
//  Draw a white slice for the 0
if (barcode.charAt (i) == '0')
{
page.setColor (spaceColor);
}
//  Draw a black slice for the '1'
else if (barcode.charAt (i) == '1')
{
page.setColor (barColor);
}
//  Draw a red slice to show something graphically
else
{
page.setColor (errorColor);
}

//  Update the coordinates
x += sliceWidth;

//  Draw the slices at the specified coordinates
page.fillRect (x, 0, sliceWidth, height);
}
}
}```

The UPC must be exactly 12 digits before we can generate the barcode from it.

```//---------------------------------------------------------------------
//  Checks if the UPC is valid. a UPC is valid if it consists
//  of exactly 12 digits.
//---------------------------------------------------------------------
public void validateUPC ()
{
valid = UPC.matches ("[0-9]{12}?");
}```

The major method that generates the barcode from the UPC field.

```//---------------------------------------------------------------------
//  Generate the barcode from the UPC...
//---------------------------------------------------------------------
public void generateBarcode ()
{
if (isValid ())
{
barcode = quiteZone + leftStartCode +
leftCodes[charToInteger (UPC.charAt (0))] +
leftCodes[charToInteger (UPC.charAt (1))] +
leftCodes[charToInteger (UPC.charAt (2))] +
leftCodes[charToInteger (UPC.charAt (3))] +
leftCodes[charToInteger (UPC.charAt (4))] +
leftCodes[charToInteger (UPC.charAt (5))] +
centerCode +
rightCodes[charToInteger (UPC.charAt (6))] +
rightCodes[charToInteger (UPC.charAt (7))] +
rightCodes[charToInteger (UPC.charAt (8))] +
rightCodes[charToInteger (UPC.charAt (9))] +
rightCodes[charToInteger (UPC.charAt (10))] +
rightCodes[charToInteger (UPC.charAt (11))] +
rightEndCode + quiteZone;

repaint ();
}
}```

#### UPCField

##### Methods

Calls the parent (`MNDigitField`) constructor to create a text field that only accepts digits with a maximum of `N `(12) digits. When exactly `M `(11) digits are entered, the `MComponent `('Generate Check Digit' button) is acted upon (enabled). Otherwise, the action is undone (button disabled). When exactly `N `(12) digits are entered, the `NComponent `('Generate Bar Code' button) is acted upon (enabled). Otherwise, the action is undone (button disabled).

```//---------------------------------------------------------------------
//  Create a field where user enters UPC code.
//---------------------------------------------------------------------
public UPCField (JButton MButton, JButton NButton)
{
//  Create a 12 digit field having width of 8 cols
//  M = 11, N = 12, MComponent = MButton, NComponent = NButton
//  cols = 8.
<a href=""%22#MNDigitField""">super</a> (11, 12, MButton, NButton, 8);
}```

If the UPC is 11 digits long, then generate the check digit, and append it to the end of the UPC to form the 12 digit valid UPC.

```//---------------------------------------------------------------------
//  Generates check digit and appends it to the upc field.
//---------------------------------------------------------------------
public void generateCheckDigit ()
{
//  Generate check digit only if there are 11 characters
if (this.howManyDigits () == 11)
{
String upc = this.getText ();
int checksum = 0;

checksum = generateCheckDigit (upc);

//  Append the check digit to the end of hte UPC
this.setText (upc + checksum);
}
}```

Generates the check digit from the first 11 digits of the UPC field.

```//---------------------------------------------------------------------
//  Generates check digit.
//---------------------------------------------------------------------
public int generateCheckDigit (String upc)
{
int checksum = 0;

for (int i = 1; i <= upc.length (); i++)
{
// even
if (i % 2 == 0)
checksum += charToInteger (upc.charAt (i - 1)) * 1;
//  odd
else
checksum += charToInteger (upc.charAt (i - 1)) * 3;
}

return ( 10 - ( checksum % 10 )  ) % 10;
}```

Tells whether the check digit is valid.

```//---------------------------------------------------------------------
//  Makes sure that the check digit is valid.
//---------------------------------------------------------------------
public boolean isCheckDigitValid ()
{
if (howManyDigits () == 12)
{
String upc = this.getText ();

//  The check digit entered by the user
//  character 12 (start at 0)
int checkDigitEntered = charToInteger (upc.charAt (11));

//  the generate (valid) check digit
int validCheckDigit = this.generateCheckDigit (upc.substring (0, 11));

return checkDigitEntered == validCheckDigit;
}

return false;
}```

#### MNDigitField

This is a class that allows you to create a text field with only digits and with a maximum of `N `digits. Once the number of digits becomes `M`, an `MAction `is performed on the `MComponent`. And once the number of digits is not `M `anymore, an `MReaction `is performed. The same is true for `N`. Once the number of digits becomes `N`, an `NAction `is performed on the `NComponent`, and once the number of digits is not `N `anymore, an `NReaction `is performed.

```public MNDigitField (int m, int n, JComponent mComp, JComponent nComp, int cols)
{
//  Specify the width of the text field in terms of columns
super (cols);

//  Set M and N
this.M = m;
this.N = n;

//  create component actors
this.MComponentActor = new ComponentActor (mComp);
this.NComponentActor = new ComponentActor (nComp);

//  Set the action type to ENABLE (This is default type, but I'm
//  resetting to emphasize the idea)
this.MComponentActor.setActionType (ComponentActor.ENABLE);
this.NComponentActor.setActionType (ComponentActor.ENABLE);

//  Add document listener to the text field
}```

The `NDigitDocument `class is responsible for not allowing characters other than digits to be entered, and for not allowing the number of characters to exceed `N`.

```static class NDigitDocument extends PlainDocument
{
public void insertString (int offs, String str, AttributeSet a)
{
if (str == null)
return;

//  Don't allow number of characters to exceed N
//  (The +1 is because insertString is called before insertupdate)
if (currentLength + 1 > N)
return;

//  Validate that the characters of the string are digits
for (int i = 0; i < str.length(); i++)
{
if (!Character.isDigit (str.charAt (i)))
return;
}

super.insertString(offs, str, a);
}
}```

The `MNDocumentListener `class listens to the user's interaction with the `textfield`, and decides what to do based on the number of characters in the text field.

```class MNDocumentListener implements DocumentListener
{
//-----------------------------------------------------------------
//  Called when users insert characters.
//-----------------------------------------------------------------
public void insertUpdate (DocumentEvent e)
{
decide (e);
}

//-----------------------------------------------------------------
//  Called when users remove characters (DEL or Back Space).
//-----------------------------------------------------------------
public void removeUpdate (DocumentEvent e)
{
decide (e);
}

//-----------------------------------------------------------------
//  Do an action based on the values of M and N. In our case, the
//  action is to enable or disable (reaction) the MComponent
//  and NComponent.
//-----------------------------------------------------------------
public void decide (DocumentEvent e)
{
Document doc = (Document)e.getDocument();
currentLength = doc.getLength ();

//  Enable MComponent if M digits reached
//  Otherwise, disable it.
MComponentActor.<a href=""%22#public"">decide</a> (currentLength == M);

//  Enable NComponent if N digits reached
//  Otherwise, disable it.
NComponentActor.<a href=""%22#public"">decide</a> (currentLength == N);
}
}```

#### Actor

This is an `abstract `class that performs an action and reverses this action based on a condition. The action performed is based on the `actionType`.

```public void decide (boolean condition)
{
if (condition)
doAction ();
else
undoAction ();
}```

#### ComponentActor

This class inherits from the `Actor abstract` class. It acts on a Java GUI component. If the `actionType `is `ENABLE`, then this class would enable or disable a `JComponent `based on a condition.

The method called in our program to enable the 'Generate Check Digit' and 'Generate Bar Code' buttons is:

```//---------------------------------------------------------------------
//  Perform an action.
//---------------------------------------------------------------------
public void doAction ()
{
//  Do nothing if no component is supplied
if (component == null)
return;

//  Perform action based on action type
switch (actionType)
{
case ENABLE:
component.setEnabled (true);
break;
case MAKE_VISIBLE:
component.setVisible (true);
break;
}
}```

The method called in our program to disable the 'Generate Check Digit' and 'Generate Bar Code' buttons is:

```//---------------------------------------------------------------------
//  Reverse the action..
//---------------------------------------------------------------------
public void undoAction ()
{
//  Do nothing if no component is supplied
if (component == null)
return;

//  Perform reaction based on action type
switch (actionType)
{
case ENABLE:
component.setEnabled (false);
break;
case MAKE_VISIBLE:
component.setVisible (false);
break;
}
}```

## Conclusion

I created this program and wrote the article in 2005. I got it submitted to Code Project, but at that time Java was not supported on this site. I guess now I got back the opportunity to share it with the community. I hope it would be fun... Enjoy!

Just in case you wondered what ASTI SPUMANTE means. It is a "semi-dry sparkling wine produced from the Moscato di Canelli grape in the village of Asti, in the Piedmont region of Italy".

## Revision History

• 06/01/2008: Original article submitted

## Share

 Software Developer Qualtrics United States

## You may also be interested in...

 First Prev Next
 barcode library Tertalu12-Mar-13 18:31 Tertalu 12-Mar-13 18:31
 that's good sonnykwe10-Jun-08 12:25 sonnykwe 10-Jun-08 12:25
 Last Visit: 31-Dec-99 19:00     Last Update: 1-May-16 0:47 Refresh 1