UPC-2 is a simpler variation of the UPC-5 barcode designed to contain 2 digits of data.

UPC-2 Barcode

UPC-2 Barcode


The checksum (or parity) for the UPC-2 format is used only to encode the barcode, and therefore is not coded directly, and out of all the UPc barcodes, is the only one in this series which does not use modulo 10.

The parity is simply the two digits treated as an integer and then applying modulo 4 to it, and the remainder is the parity.

Like with UPC-5, UPC-2 only has a left guard and centre guard (which is places after the third digit), which are encoded as 1011 and 01 respectively.

We then apply the odd or even encoding based on the parity string we determine from the parity

0 11
1 10
2 01
3 00

The odd and even encodings are the same as the ones for the UPC-5 format

Digit Odd Even
0 0001101 0100111
1 0011001 0110011
2 0010011 0011011
3 0111101 0100001
4 0100011 0011101
5 0110001 0111001
6 0101111 0000101
7 0111011 0010001
8 0110111 0001001
9 0001011 0010111


Here is the code to encode the barcode. The full source code is available here

namespace BarcoderLib
{
    public class BarcodeUPC2 
    {
        private string gLeftGuard = "1011";
        private string gCentreGuard = "01";
        private string[] gOdd = { "0001101", "0011001", "0010011", "0111101", "0100011", "0110001", "0101111", "0111011", "0110111", "0001011" };
        private string[] gEven = { "0100111", "0110011", "0011011", "0100001", "0011101", "0111001", "0000101", "0010001", "0001001", "0010111" };
        private string[] gParity = { "11", "10", "01", "00" };

        public Bitmap Encode(string message)
        {
            string encodedMessage;

            Bitmap barcodeImage = new Bitmap(250, 100);
            Graphics g = Graphics.FromImage(barcodeImage);


            Validate(message);
            encodedMessage = EncodeBarcode(message);

            PrintBarcode(g, encodedMessage, message, 250, 100);

            return barcodeImage;
        }
        private void Validate(string message)
        {

            Regex reNum = new Regex(@"^\d+$");
            if (reNum.Match(message).Success == false)
            {
                throw new Exception("Encode string must be numeric");
            }

            if (message.Length != 2)
            {
                throw new Exception("Encode string must be 2 digits long");
            }
        }

        private void PrintBarcode(Graphics g, string encodedMessage, string message, int width, int height)
        {
            SolidBrush whiteBrush = new SolidBrush(Color.White);
            SolidBrush blackBrush = new SolidBrush(Color.Black);
            Font textFont = new Font(FontFamily.GenericMonospace, 10, FontStyle.Regular);
            g.FillRectangle(whiteBrush, 0, 0, width, height);

            int xPos = 20;
            int yTop = 20;
            int barHeight = 50;

            for (int i = 0; i < encodedMessage.Length; i++)
            {
                if (encodedMessage[i] == '1')
                {
                    g.FillRectangle(blackBrush, xPos, yTop, 1, barHeight);
                }
                xPos += 1;
            }

            xPos = 20;
            yTop -= 17;
            for (int i = 0; i < message.Length; i++)
            {
                g.DrawString(message[i].ToString(), textFont, blackBrush, xPos, yTop);
                xPos += 8;
            }
        }

        private string EncodeBarcode(string message)
        {
            int i;
            int parityCode = CalcParity(message);
            char parity;
            string encodedString = gLeftGuard;

            for (i = 0; i < 2; i++)
            {
                parity = gParity[parityCode][i];
                if (parity == '1')
                {
                    encodedString += gOdd[Convert.ToInt32(message[i].ToString())];
                }
                else
                {
                    encodedString += gEven[Convert.ToInt32(message[i].ToString())];
                }
                if (i < 1)
                {
                    encodedString += gCentreGuard;
                }
            }

            return encodedString;
        }

        private int CalcParity(string message)
        {
            int parity = Convert.ToInt32(message) % 4;
            return parity;

        }
    }
}


Share