Files
QR-master/articles/devto-hashnode/devto-barcode-encoding-algorithms-ean13-code128.md
2026-08-05 19:32:52 +02:00

7.8 KiB
Raw Permalink Blame History

title, description, tags, keywords, canonical_url
title description tags keywords canonical_url
Barcode Encoding Algorithms: EAN-13 & Code 128 Checksum Math from Scratch in JavaScript A deep computer science exploration of 1D barcode encoding algorithms, covering Modulo 10 and Modulo 103 checksum calculations, building a free barcode generator and a code 128 barcode generator in TypeScript. javascript, typescript, algorithms, computer-science free barcode generator, ean code generator, code 128 barcode generator, qr barcode, barcode code generator, free barcode, print barcode https://www.qrmaster.net/blog/barcode-generator-tool

Barcode Encoding Algorithms: EAN-13 & Code 128 Checksum Math from Scratch in JavaScript

Long before 2D QR codes dominated digital marketing, one-dimensional (1D) linear barcodes—such as EAN-13 in retail products and Code 128 in logistics and shipping—revolutionized inventory automation.

Building a free barcode generator or an ean code generator requires understanding that barcode scanner guns and camera libraries do not "guess" numbers from images; they decode precise binary bit patterns (bars and spaces) and verify mathematical checksums (Modulo 10 for EAN-13; Modulo 103 for Code 128).

In this deep computer science guide, we will examine the bit pattern structures of EAN-13 and Code 128, derive their checksum formulas, and implement a pure TypeScript barcode code generator without any external npm dependencies.


1. Deconstructing EAN-13 Retail Barcode Encoding

An EAN-13 (European Article Number) barcode produced by an ean code generator encodes exactly 13 numeric digits:

  • First 23 digits: Country Prefix (e.g., 400440 for Germany, 000019 for US/Canada).
  • Next 45 digits: Manufacturer Identification Code.
  • Next 45 digits: Unique Item / Product Code.
  • 13th Digit: Mathematical Modulo 10 Checksum Digit.
  Country  Manufacturer   Product   Check
   ┌──┴──┐   ┌────┴────┐ ┌───┴───┐   ┌┴┐
   4 0 0 1 2 3 4 5 6 7 8 9 5

The EAN-13 Modulo 10 Checksum Formula

To compute the 13th check digit for a 12-digit input in an ean code generator:

  1. Sum all digits in odd-numbered positions (1st, 3rd, 5th, 7th, 9th, 11th).
  2. Sum all digits in even-numbered positions (2nd, 4th, 6th, 8th, 10th, 12th) and multiply by 3.
  3. Add the two sums together.
  4. The check digit is the number required to reach the next multiple of 10:
\text{Check Digit} = (10 - (\text{Total Sum} \pmod{10})) \pmod{10}

Checksum Example Calculation:

Take the 12-digit string 400123456789:

  • Odd sum: 4 + 0 + 2 + 4 + 6 + 8 = 24
  • Even sum: (0 + 1 + 3 + 5 + 7 + 9) \times 3 = 25 \times 3 = 75
  • Total: 24 + 75 = 99
  • Check digit: (10 - (99 \pmod{10})) \pmod{10} = (10 - 9) \pmod{10} = 1
  • Final 13-digit EAN-13 code: 4001234567891

2. Deconstructing Code 128 High-Density Barcodes

While EAN-13 is strictly numeric, a code 128 barcode generator creates high-density alphanumeric barcode formats capable of encoding all 128 ASCII characters (uppercase/lowercase letters, digits, punctuation, and control codes).

Code 128 Structure

A Code 128 qr barcode structure consists of:

  1. Start Character: Start A (103), Start B (104), or Start C (105).
  2. Data Symbol Characters: Each character is represented by 11 modules composed of 3 bars and 3 spaces.
  3. Check Character: Modulo 103 checksum value.
  4. Stop Character: 13-module pattern (1100011101011).

The Code 128 Modulo 103 Checksum Formula

\text{Checksum Value} = \left( \text{Start Value} + \sum_{i=1}^{N} (i \times \text{Symbol Value}_i) \right) \pmod{103}

3. Pure TypeScript Barcode Engine (No External Dependencies)

Let's build a standalone TypeScript module (src/services/barcodeEngine.ts) for a free barcode generator that computes EAN-13 checksums and renders a vector SVG print barcode.

src/services/barcodeEngine.ts

export class BarcodeEngine {
  /**
   * Computes the Modulo 10 Checksum digit for a 12-digit EAN string in an ean code generator.
   */
  public static calculateEAN13Checksum(digits12: string): number {
    if (!/^\d{12}$/.test(digits12)) {
      throw new Error('EAN-13 input must be exactly 12 numeric digits.');
    }

    let oddSum = 0;
    let evenSum = 0;

    for (let i = 0; i < 12; i++) {
      const digit = parseInt(digits12[i], 10);
      if (i % 2 === 0) {
        oddSum += digit;
      } else {
        evenSum += digit;
      }
    }

    const totalSum = oddSum + evenSum * 3;
    const remainder = totalSum % 10;
    return remainder === 0 ? 0 : 10 - remainder;
  }

  /**
   * EAN-13 Binary Bit Patterns for L, G, and R encodings.
   */
  private static L_PATTERNS = [
    '0001101', '0011001', '0010011', '0111101', '0100011',
    '0110001', '0101111', '0111011', '0110111', '0001011'
  ];

  private static R_PATTERNS = [
    '1110010', '1100110', '1101100', '1000010', '1011100',
    '1001110', '1010000', '1000100', '1001000', '1110100'
  ];

  /**
   * Generates a crisp vector SVG string for an EAN-13 barcode.
   */
  public static generateEAN13SVG(digits12: string): string {
    const checkDigit = this.calculateEAN13Checksum(digits12);
    const fullEan13 = digits12 + checkDigit.toString();

    // Structural guard and center patterns
    const GUARD_START = '101';
    const GUARD_CENTER = '01010';
    const GUARD_END = '101';

    let bitPattern = GUARD_START;

    // Encode Left 6 Digits (using L-Patterns for simplicity)
    for (let i = 1; i <= 6; i++) {
      const digit = parseInt(fullEan13[i], 10);
      bitPattern += this.L_PATTERNS[digit];
    }

    bitPattern += GUARD_CENTER;

    // Encode Right 6 Digits (using R-Patterns)
    for (let i = 7; i <= 12; i++) {
      const digit = parseInt(fullEan13[i], 10);
      bitPattern += this.R_PATTERNS[digit];
    }

    bitPattern += GUARD_END;

    // Render SVG
    const moduleWidthPx = 3;
    const heightPx = 120;
    const totalWidthPx = bitPattern.length * moduleWidthPx + 40; // 40px margin

    let svgPaths = '';
    for (let i = 0; i < bitPattern.length; i++) {
      if (bitPattern[i] === '1') {
        const x = 20 + i * moduleWidthPx;
        svgPaths += `<rect x="${x}" y="10" width="${moduleWidthPx}" height="${heightPx - 30}" fill="#000000" />`;
      }
    }

    // Add human-readable numbers text below bars
    const textSvg = `<text x="${totalWidthPx / 2}" y="${heightPx - 5}" font-family="monospace" font-size="16" text-anchor="middle">${fullEan13}</text>`;

    return `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${totalWidthPx} ${heightPx}" width="${totalWidthPx}" height="${heightPx}">
  <rect width="100%" height="100%" fill="#FFFFFF" />
  ${svgPaths}
  ${textSvg}
</svg>`.trim();
  }
}

4. Verification & Testing

Let's write a unit test to verify checksum calculation and SVG rendering output.

import { BarcodeEngine } from '../src/services/barcodeEngine';

describe('BarcodeEngine', () => {
  test('should correctly compute EAN-13 Modulo 10 Checksum', () => {
    // 400123456789 -> Check digit should be 1
    const check = BarcodeEngine.calculateEAN13Checksum('400123456789');
    expect(check).toBe(1);
  });

  test('should generate valid vector SVG string', () => {
    const svg = BarcodeEngine.generateEAN13SVG('400123456789');
    expect(svg).toContain('<svg');
    expect(svg).toContain('4001234567891'); // Includes computed check digit
    expect(svg).toContain('</svg>');
  });
});

Conclusion

Understanding the binary bit patterns and mathematical checksum algorithms behind 1D barcodes allows developers to build a fast free barcode generator without relying on heavy external dependencies.

To generate free high-resolution EAN-13, UPC-A, and Code 128 barcodes online, check out QR Master Free Barcode Generator.