DEV Community 👩‍💻👨‍💻

Saulo Dias
Saulo Dias

Posted on • Updated on

Generating Valid Code 128 Barcodes with Javascript

To generate a valid Code 128 barcode you need to follow some rules. It must contain a start chararacter, that indicates which character set you want to represent; the data characters, the characters that will be encoded; the checksum, a single character for error checking; and finally, a stop character, to indicate the end of the barcode.

In the ID Automation Code 128 Barcode Font User Manual
you can find detailed instructions on what those characters (Start and Stop) are and how to generate a checksum for the data you want to encode.

For most applications Set B or C is what you want. Set B contains digits, uppercase and lowercase letters, and some special characters. Set C is used to represent numbers from 00 to 99, which is useful when you want to represent huge strings of numbers. Set A contains digits, uppercase letters, and a bunch of control characters, which might be useful in some specific applications.

You can also switch between the three code sets in the same barcode, as there are control characters for that purpose in each set. However, this will not be covered in this post.

To generate the valid code we must pass the text to be encoded to the encodeToCode128 function.

const checkbox = document.getElementById('withtext')

function toSetC(text) {
  return text.match(/\d{2}/g).map((ascii, index) => {
    var codeC = Number(ascii);
    var charCode = codeC > 94 ? codeC + 100 : codeC + 32;
    return String.fromCharCode(charCode)
  }).join('');
}

function checkSum128(data, startCode) {
  var sum = startCode;
  for (var i = 0; i < data.length; i++) {
    var code = data.charCodeAt(i);
    var value = code > 199 ? code - 100 : code - 32;
    sum += (i + 1) * (value);
  }

  var checksum = (sum % 103) + 32;
  if (checksum > 126) checksum = checksum + 68 ;
  return String.fromCharCode(checksum);
}

function encodeToCode128(text, codeABC = "B") {
  var startCode = String.fromCharCode(codeABC.toUpperCase().charCodeAt() + 138);
  var stop = String.fromCharCode(206);

  text = codeABC == 'C' && toSetC(text) || text;

  var check = checkSum128(text, startCode.charCodeAt(0) - 100);

  text = text.replace(" ", String.fromCharCode(194));

  return startCode + text + check + stop;
}

function renderBarcodes(withText = true) {
  var barcodeElements = document.querySelectorAll(".barcode");
  var codes = [];
  barcodeElements.forEach((e) => {
    var code = e.attributes["data-barcode"]?.value;
    if (!code) return;
    var set = e.attributes["data-set"]?.value;
    e.innerHTML = encodeToCode128(code, set);
    e.classList.toggle('with-text', withText)
  });
}

renderBarcodes();

checkbox.addEventListener('change', (event) => {
  renderBarcodes(event.currentTarget.checked)
});
Enter fullscreen mode Exit fullscreen mode

To generate the valid barcode we just add the barcode class to an empty div and pass the data-barcode attribute with the data we want. This is a completely arbitrary parameter name, but it is the parameter the renderBarcodes function will look for.

   <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Libre+Barcode+128">

   <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Libre+Barcode+128+Text">

   <input type="checkbox" id="withtext" name="Show Barcode With Text" checked>
   <label for="withtext">Show Barcode With Text</label>
   <br /> <br />

   <div class="barcode" data-barcode="https://dev.to/saulodias"></div>
   <br />
   This code contains only digits, and can have a shorter barcode when using Set C
   <div class="barcode" data-barcode="0123456789"></div>
   <br />
   Same data as the barcode above but with a shorter barcode.
   <div class="barcode" data-barcode="0123456789" data-set="C"></div>
Enter fullscreen mode Exit fullscreen mode

Here are is the CSS to apply correctly apply the Libre Barcode fonts used.

.barcode {
  font-family: "Libre Barcode 128", "Courier New", Courier, monospace;
  font-weight: normal;
  font-size: 52px;
  white-space: nowrap;
}

.with-text {
  font-family: "Libre Barcode 128 Text";
}
Enter fullscreen mode Exit fullscreen mode

See the JS Fiddle Example here.

Length Optimization

Here is an example switching code set for optimization

The challenge is to find the best combination to optimize the number of characters used, making the barcode shorter. This is explained in [more details on Wikipedia.]
To decide when switch to code C I have used the criteria in this Wikipedia Page

Additional notes

If you prefer, the fonts used in the example can be downloaded here:

On Stack Overflow Taw implemented this in C#. I used his implementation as reference.

P.S. When generating server-side PDFs, which is something I needed to do you might need to install the fonts to the server, if you have any trouble with font-face and/or the CDN fonts. In any case I do not like to use CDN fonts for several reasons out of the scope of this post.

Top comments (2)

Collapse
 
janborup profile image
Jan Borup Coyle • Edited on

There is an error in your short barcode has the number is 95, 96, 97, 98 og 99.
Then the barcode is formated with a wrong char.
/Cheers

Image description

Collapse
 
saulodias profile image
Saulo Dias • Edited on

This bug had been caught but I only corrected it in the version with the dynamic optimization. I have updated the jsfiddle and the code in the post. Thanks for reporting!

Tired of sifting through your feed?

Find the content you want to see.

Change your feed algorithm by adjusting your experience level and give weights to the tags you follow.