UPC-5 is a variation on the UPC-A barcode designed to contain 5 digits of data.

UPC-5 Barcode

The checksum (or parity) for the UPC-5 format is used only to encode the barcode, and therefore is not coded directly.

Calculating the parity uses the same modulo 10 method as the UPC-A, except that the weightings are different. Odd-numbered positions are weighted 3, while even-numbered positions are weighted 9.

Once we have the weighted sum, we apply a modulo 10 to the weighted sum, which gets the remainder after applying a modulo of 10 to the weighted sum.

The parity is then 10 – (modulo 10 of the weighted sum).

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

The 5 digits are then encoded using either odd or even encoding, which is determined by the parity string.

 0 00111 1 01011 2 01101 3 01110 4 10011 5 11001 6 11100 7 10101 8 10110 9 11010

The odd and even encodings are the same as the ones for the UPC-E 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 BarcodeUPC5
{
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 = {"00111", "01011", "01101", "01110", "10011", "11001", "11100", "10101", "10110", "11010"};

private int[] gWeighting = { 3, 9, 3, 9, 3};

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 != 5)
{
throw new Exception("Encode string must be 5 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 += 7;
}
}

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

for (i = 0; i < 5; 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 < 4)
{
encodedString += gCentreGuard;
}
}

return encodedString;
}

private int CalcParity(string message)
{
int sum = 0;
int parity = 0;

for (int i = 0; i < 5; i++)
{
sum += Convert.ToInt32(message[i].ToString()) * gWeighting[i];
}

parity = 10 - (sum % 10);
if (parity == 10)
{
parity = 0;
}
return parity;
}

}
}

```