How bar codes are generated

Posted on 2005-04-20
Medium Priority
Last Modified: 2013-12-03
Well, it is half a question, half a sharing of knowledge. I have to implement in my code the bar code generation, but not using 3rd party componenets, I needed it to be made by MY code, as finally the bar code ended up as vector images, not bitmaps.

The fact is that I was unable to find the algorithms to generate the bars in any google search! May be it is short of industrial secret... finally, I found a partial reference on how to do it, and checking the bars I generated with real examples, I managed to complete the algorithm to be able to produce 100% correct bar codes... on one type only, as there existe docens of types!

The format I worked out is called UPCA, and is the tipical one in the food pakages. But it only allows to represent 12 digits (0 to 9), no letters or punctuations.

I would like to get more format especifications so I can generate other formats.

In the meanwhile, I will post as an answer to this question, the internal workings of this format, so it is not a "secret" anymore. I haven't read in any page that the algorithm is copyrighted so I suppose it is not ilegal to publish it. If it is, please let me know.

Links are wellcome as long as they explain the way you construct the bars, not only the checksums, as this is the easy part (most of the format use the same algorithm to compute checksums).
Question by:Sergio_Hdez
LVL 15

Expert Comment

ID: 13822308
If you talking about general barcoding, there are quite a number of versions, but basically it is just a font, nothing special about any barcodes really.
Most of the time you have to pay/buy a selection of barcodes as they, in general, are copyrighted. There are many different versions of barcodes used depending on the section of industry you are currently in.

Author Comment

ID: 13822381
OK, I will post the first format, "UPC A": The goal is to convert a 11 digits -or less- integer into a bar code. The bar code is formed with lines of 3 different widths: from 1 to 3 (the actual units are irrelevant, scale will not matter to the gun reader).

So our goal is to convert a number, like 411223 into a serie of 1, 2 and 3s, in the way '11132113211321132113211113211111222122212122212214111231111', that you can directly draw: The first width "1" painted on black, the next one on white, then black, and so on. It is supposed that you have to get the last width painted on black, to be readable, of course!

So, how to convert '411223' into '11132113211321132113211113211111222122212122212214111231111' (the example IS REAL, use it to check your algorithms!)?

The idea is:

A) Complete the number up to 11 digits: from '411223' to '00000411223', calculate a checksum digit (it is '5' in the example) and add it to the end: '000004112235'

B) Now, convert each digit to a set of 3 widths (ther is a table for this), and put it all together, adding some exta "1"s at the beginig ('111'), middle ('11111') and end ('111'). These are the thin lines you see at both ends in the bar codes ni the shop.

C) Draw the witdhs you calculated: One black, next white, and so on.


  Cod:= Copy(Cod,1,11); //Initial string '411223'
  while length(Cod)<11 do Cod:= '0'+Cod; //Now with leading zeros becomes '000000411223'
  //Calculate digit 12nd (the checksum)
  CheckSum:= 0;
  for i:= 1 to length(Cod) do begin
    Num:= StrToInt(copy(Cod,i,1));
    Checksum:= CheckSum + Num * iif((i mod 2)=1, 3, 1);
  CheckSum:= 10 - (CheckSum mod 10);
  if (CheckSum=10) then CheckSum:= 0;
  //Add extra digit, in this example it is a 5
  result:= Cod + IntToStr(CheckSum); //We have now the final digits '0000004112235'


function Txt2Barras(Cod: string): string;
var i, Num: integer;
  //This array is the conversion from one digit to 4 widths
  Codes: array [0..9] of string = ('3211', '2221', '2122', '1411', '1132',
       '1231', '1114', '1312', '1213', '3112');
  IniCode: string = '111';   //To be added at beginning and end
  MedCode: string = '11111'; //In the middle of the 12 digits, add this
  result:= IniCode;
  //Now comes the first 6 digits, plus '11111', then last 6 digits, and finally '111'
  for i:= 1 to 12 do begin
    Num:= StrToInt(copy(Cod,i,1));
    result:= result + Codes[Num];
    //Thin lines 11111 in the middle...
    if (i=6) then
      result:= result + MedCode;
  result:= result+IniCode;

For test purpouses, the final width list, in this example, is:

Finally, just note that the bar codes examples print the numbers under the bars, in the format '0--000004--11223--5', where the places filled with '--' are ocuppied with bars, separating each group of digits (this is usefull when the bar code reader can't read one and you have to type it directly).

The above code is checke to be working 100% OK, so you can use it with little to none test.

Hope others have more info on this matter.

Author Comment

ID: 13822407
mikelittlewood, I know you can use special fonts to print bar codes in special printers, but I needed it to be vectorial information, so I really needed it to be done by my code, as the output is not only special printers or fixed sizes, I have to be able to resize, rotate, strecht and so on the graphic object I cobstruct... I need the real internals on how to generate the lines, not only the fonts.
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 13822420
Ops, I wrote something badly: The widths can vary from 1 to 4, not to 3 as I mentioned early. In the digit-to-width table there are some 4s!

Author Comment

ID: 13822464
mikelittlewood, when you talk about buying barcodes, I suppose you are talking about assigning those barcodes to your products so they do not conflict with other companys products on the market, like buying a range of IPs address for you web site (correct me if I missunderstood you).

But, in my case, I just needed to print some internal codes in that format (to a label printer or a laser one, depends on the final user likings) so the end user can type then in my app or just "shot" the barcodes with a reader, so I just needed it to be a "output internal format" to avoid typo errors to the end user of the app.

If you plan to print barcodes in things that will be readed by 3rd party companies, you need to "buy" a range of numbers so no other product will use those codes on their labels, keep this on mind!
LVL 17

Assisted Solution

mokule earned 1600 total points
ID: 13822788
Look at the project

In its sources find rpmdbarcode.pas.
These are the codes it generate
 TRpBarcodeType = (bcCode_2_5_interleaved,
LVL 15

Expert Comment

ID: 13822810
Have you got a barcode scanner already? Don't they usually come with a set of barcode software/fonts that you can use? Or does it not come with the barcode version you want to work with.
Ive had a quick look around other PAQs on EE and there does seem to be quite a few free components and code that might be able to point you in the right direction.

I have to admit that Ive never had to write software where you manually create the lines, Ive just used the standard barcode fonts with the scanners I use.

Accepted Solution

vadim_ti earned 400 total points
ID: 13823184
try to download from this link, i think it is what you search


Author Comment

ID: 13824514
Hey, you both gave me fantastic links! Reverse inginering the barcode was pleasant, but this info could had save me a lot of time.

mokule : This was EXACTLY what I was looking for, it include 2D format I only dreamed to find! Thanx a lot, you win the points.

vadim_ti : This doc is perfect, it explain the UPC and similar formats in GREAT detail, including posibilities I didn't know they existed, like aditional digits. I will split some of the points to you.

mikelittlewood : I have one scanner for testing pourpouse, it comes with a CD with a nasty app to generate bar codes, but I needed to do it my self and not using tricks like fonts, it had to be the "linux way". Thanxs anyway.

Author Comment

ID: 13824551
Ops, acepted answer is wrong, splitting points for first time is confussing... but point have been splited ok I hope!

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses
Course of the Month15 days, 10 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question