How bar codes are generated

Posted on 2005-04-20
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

    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.
    LVL 6

    Author Comment

    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.
    LVL 6

    Author Comment

    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.
    LVL 6

    Author Comment

    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!
    LVL 6

    Author Comment

    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

    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

    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.
    LVL 6

    Accepted Solution

    try to download from this link, i think it is what you search
    LVL 6

    Author Comment

    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.
    LVL 6

    Author Comment

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

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Maximize Your Threat Intelligence Reporting

    Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

    Suggested Solutions

    Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
    Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
    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…
    In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor ( If you're interested in additional methods for monitoring bandwidt…

    761 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

    Need Help in Real-Time?

    Connect with top rated Experts

    10 Experts available now in Live!

    Get 1:1 Help Now