Link to home
Start Free TrialLog in
Avatar of Sergio_Hdez
Sergio_Hdez

asked on

How bar codes are generated

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).
Avatar of Mike Littlewood
Mike Littlewood
Flag of United Kingdom of Great Britain and Northern Ireland image

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.
Avatar of Sergio_Hdez
Sergio_Hdez

ASKER

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.

CHECKSUM:

  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);
  end;
  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'

CONVERT TO BLACK-WHITE WIDTHS LIST:

function Txt2Barras(Cod: string): string;
var i, Num: integer;
const
  //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
begin
  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;
  end;
  result:= result+IniCode;
end;

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

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.
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.
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!
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!
SOLUTION
Avatar of mokule
mokule
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
Ops, acepted answer is wrong, splitting points for first time is confussing... but point have been splited ok I hope!