Xerobit

GS1-128 Barcode Generator

Enter your product data to generate a GS1-128 barcode using standard application identifiers. The tool encodes the GTIN, batch number, expiration date and serial number into a single symbol with FNC1 separators. Everything runs locally in your browser and nothing is uploaded.

Barcode

(01)00614141000012(17)251231(10)BATCH01(21)SN123456
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 396 100" width="792" height="200"><rect x="0" y="0" width="396" height="100" fill="white"/><rect x="10" y="0" width="2" height="80" fill="black"/><rect x="13" y="0" width="1" height="80" fill="black"/><rect x="16" y="0" width="3" height="80" fill="black"/><rect x="21" y="0" width="4" height="80" fill="black"/><rect x="26" y="0" width="1" height="80" fill="black"/><rect x="28" y="0" width="3" height="80" fill="black"/><rect x="32" y="0" width="2" height="80" fill="black"/><rect x="36" y="0" width="2" height="80" fill="black"/><rect x="39" y="0" width="2" height="80" fill="black"/><rect x="43" y="0" width="2" height="80" fill="black"/><rect x="46" y="0" width="2" height="80" fill="black"/><rect x="50" y="0" width="2" height="80" fill="black"/><rect x="54" y="0" width="2" height="80" fill="black"/><rect x="58" y="0" width="1" height="80" fill="black"/><rect x="63" y="0" width="1" height="80" fill="black"/><rect x="65" y="0" width="2" height="80" fill="black"/><rect x="70" y="0" width="1" height="80" fill="black"/><rect x="74" y="0" width="1" height="80" fill="black"/><rect x="76" y="0" width="2" height="80" fill="black"/><rect x="81" y="0" width="1" height="80" fill="black"/><rect x="85" y="0" width="1" height="80" fill="black"/><rect x="87" y="0" width="2" height="80" fill="black"/><rect x="90" y="0" width="2" height="80" fill="black"/><rect x="94" y="0" width="2" height="80" fill="black"/><rect x="98" y="0" width="2" height="80" fill="black"/><rect x="101" y="0" width="2" height="80" fill="black"/><rect x="105" y="0" width="2" height="80" fill="black"/><rect x="109" y="0" width="1" height="80" fill="black"/><rect x="111" y="0" width="2" height="80" fill="black"/><rect x="115" y="0" width="3" height="80" fill="black"/><rect x="120" y="0" width="1" height="80" fill="black"/><rect x="123" y="0" width="3" height="80" fill="black"/><rect x="128" y="0" width="2" height="80" fill="black"/><rect x="131" y="0" width="3" height="80" fill="black"/><rect x="136" y="0" width="1" height="80" fill="black"/><rect x="138" y="0" width="2" height="80" fill="black"/><rect x="142" y="0" width="1" height="80" fill="black"/><rect x="144" y="0" width="2" height="80" fill="black"/><rect x="148" y="0" width="3" height="80" fill="black"/><rect x="153" y="0" width="2" height="80" fill="black"/><rect x="156" y="0" width="2" height="80" fill="black"/><rect x="161" y="0" width="2" height="80" fill="black"/><rect x="164" y="0" width="2" height="80" fill="black"/><rect x="168" y="0" width="1" height="80" fill="black"/><rect x="172" y="0" width="1" height="80" fill="black"/><rect x="175" y="0" width="1" height="80" fill="black"/><rect x="177" y="0" width="4" height="80" fill="black"/><rect x="182" y="0" width="3" height="80" fill="black"/><rect x="186" y="0" width="1" height="80" fill="black"/><rect x="190" y="0" width="1" height="80" fill="black"/><rect x="192" y="0" width="2" height="80" fill="black"/><rect x="197" y="0" width="1" height="80" fill="black"/><rect x="199" y="0" width="1" height="80" fill="black"/><rect x="203" y="0" width="2" height="80" fill="black"/><rect x="208" y="0" width="2" height="80" fill="black"/><rect x="211" y="0" width="3" height="80" fill="black"/><rect x="217" y="0" width="1" height="80" fill="black"/><rect x="219" y="0" width="1" height="80" fill="black"/><rect x="223" y="0" width="1" height="80" fill="black"/><rect x="227" y="0" width="2" height="80" fill="black"/><rect x="230" y="0" width="2" height="80" fill="black"/><rect x="235" y="0" width="1" height="80" fill="black"/><rect x="237" y="0" width="1" height="80" fill="black"/><rect x="241" y="0" width="1" height="80" fill="black"/><rect x="244" y="0" width="3" height="80" fill="black"/><rect x="248" y="0" width="2" height="80" fill="black"/><rect x="252" y="0" width="1" height="80" fill="black"/><rect x="255" y="0" width="3" height="80" fill="black"/><rect x="260" y="0" width="2" height="80" fill="black"/><rect x="263" y="0" width="4" height="80" fill="black"/><rect x="268" y="0" width="1" height="80" fill="black"/><rect x="270" y="0" width="3" height="80" fill="black"/><rect x="274" y="0" width="2" height="80" fill="black"/><rect x="278" y="0" width="3" height="80" fill="black"/><rect x="283" y="0" width="1" height="80" fill="black"/><rect x="285" y="0" width="1" height="80" fill="black"/><rect x="288" y="0" width="3" height="80" fill="black"/><rect x="293" y="0" width="2" height="80" fill="black"/><rect x="296" y="0" width="2" height="80" fill="black"/><rect x="299" y="0" width="3" height="80" fill="black"/><rect x="303" y="0" width="1" height="80" fill="black"/><rect x="307" y="0" width="1" height="80" fill="black"/><rect x="309" y="0" width="3" height="80" fill="black"/><rect x="315" y="0" width="2" height="80" fill="black"/><rect x="318" y="0" width="1" height="80" fill="black"/><rect x="320" y="0" width="3" height="80" fill="black"/><rect x="324" y="0" width="4" height="80" fill="black"/><rect x="329" y="0" width="1" height="80" fill="black"/><rect x="331" y="0" width="2" height="80" fill="black"/><rect x="335" y="0" width="3" height="80" fill="black"/><rect x="340" y="0" width="1" height="80" fill="black"/><rect x="344" y="0" width="1" height="80" fill="black"/><rect x="346" y="0" width="2" height="80" fill="black"/><rect x="351" y="0" width="3" height="80" fill="black"/><rect x="357" y="0" width="1" height="80" fill="black"/><rect x="359" y="0" width="2" height="80" fill="black"/><rect x="362" y="0" width="2" height="80" fill="black"/><rect x="367" y="0" width="1" height="80" fill="black"/><rect x="369" y="0" width="1" height="80" fill="black"/><rect x="373" y="0" width="2" height="80" fill="black"/><rect x="378" y="0" width="3" height="80" fill="black"/><rect x="382" y="0" width="1" height="80" fill="black"/><rect x="384" y="0" width="2" height="80" fill="black"/><text x="198" y="95" font-family="monospace" font-size="12" text-anchor="middle" fill="black">(01)00614141000012(17)251231(10)BATCH01(21)SN123456</text></svg>
  • Encoded value
    (01)00614141000012(17)251231(10)BATCH01(21)SN123456
  • Check digit
    40
  • Symbol characters
    34

    Including start, check and stop characters

How to use the gs1-128 barcode generator

  1. Enter a 14-digit GTIN in the first field. Shorter numbers must be padded with leading zeros.
  2. Optionally fill in the batch number, expiry date (YYMMDD) and serial number.
  3. Click Generate to render the GS1-128 barcode as an SVG.
  4. Download or copy the SVG for use on labels, packaging or documents.

How GS1-128 encoding works

A GS1-128 barcode wraps standard Code 128 symbols with Application Identifiers (AIs) that tell scanners what each piece of data means. Every GS1-128 symbol begins with a special function character called FNC1, which signals to the reader that the data follows GS1 rules.

Fixed-length AIs such as AI(01) for GTIN (14 digits) and AI(17) for expiry date (6 digits) do not need a separator after them. Variable-length AIs like AI(10) for batch number require a FNC1 separator character when another AI follows. If the variable-length field is the last one in the symbol, no trailing separator is needed.

For example, encoding GTIN 00614141000012, expiry 251231 and batch BATCH01 produces this human-readable string; no FNC1 separator is needed because the batch number is last:

(01)00614141000012(17)251231(10)BATCH01

The gs1-128 barcode generator handles these separator rules automatically so you only need to enter the raw values.

Application Identifier reference

The following table lists the four AIs supported by this tool. Each AI has strict formatting rules that the generator validates before encoding.

AIData titleFormatLength
(01)Global Trade Item NumberNumericFixed 14
(10)Batch or lot numberAlphanumericVariable, up to 20
(17)Expiration dateNumeric YYMMDDFixed 6
(21)Serial numberAlphanumericVariable, up to 20

When combining these AIs, place fixed-length fields where possible to avoid unnecessary FNC1 separators. The generator orders them as 01, 17, 10, 21 automatically, so the only separator it ever needs is the FNC1 between the batch and serial numbers.

Code 128 subsets and efficiency

Under the hood, GS1-128 uses the same symbology as a standard Code 128 barcode. Code 128 defines three character subsets: A, B and C. Subset C encodes pairs of digits as single symbols, making it twice as compact for numeric runs.

This gs1-128 barcode generator starts in subset C for the initial FNC1 and the 14-digit GTIN. When it encounters alphabetic characters in a batch or serial number, it switches to subset B. Switching costs one symbol width, but the overall barcode stays compact because long digit strings remain in subset C.

Unlike simpler formats such as Code 39, Code 128 includes a mandatory modulo-103 check digit that catches most scanning errors. It also supports full ASCII, whereas Code 39 natively covers only 43 characters.

Common mistakes to avoid

The most frequent error when creating a GS1-128 barcode is providing a GTIN with fewer than 14 digits or a wrong check digit; the tool rejects both. An EAN-13 code, for instance, must be left-padded with a zero to become a valid GTIN-14 for AI(01). You can verify your base number with a GTIN validator before encoding.

Another issue is element order. The GS1 General Specifications allow flexibility, but many supply-chain partners expect AI(01) first, followed by AI(17), then AI(10) and AI(21), which is the order this generator uses.

Finally, remember that the human-readable text printed below the bars should show parentheses around each AI for clarity, but those parentheses are never encoded in the actual barcode data. They exist solely for people reading the label.

Where GS1-128 is used

GS1-128 is the standard barcode for logistics and healthcare. Shipping cartons carry SSCC (Serial Shipping Container Code) labels using AI(00). Pharmaceutical supply chains use the same combination of GTIN, batch, expiry and serial number for track-and-trace rules such as the EU Falsified Medicines Directive and the US Drug Supply Chain Security Act, although retail packs usually carry it in a GS1 DataMatrix rather than a linear symbol.

Retailers also rely on GS1-128 for fresh produce labels where the weight or price varies per item. Because the format supports dozens of different AIs beyond the four offered here, it scales from simple carton tracking to complex multi-attribute product identification. For 2D alternatives, consider a QR code or PDF417 barcode.

Worked examples

ExampleInputResult
Standard pharmaceutical labelGTIN (AI 01): 00614141000012; Batch or lot number (AI 10): LOT2024A; Expiry date YYMMDD (AI 17): 260630; Serial number (AI 21): SER98765; Background: whiteEncoded value: (01)00614141000012(17)260630(10)LOT2024A(21)SER98765; Check digit: 100; Symbol characters: 36
Minimal: GTIN onlyGTIN (AI 01): 00012345678905; Background: whiteEncoded value: (01)00012345678905; Check digit: 73; Symbol characters: 12
GTIN with batch and expiryGTIN (AI 01): 09501234567891; Batch or lot number (AI 10): X99; Expiry date YYMMDD (AI 17): 251200; Background: transparentEncoded value: (01)09501234567891(17)251200(10)X99; Check digit: 46; Symbol characters: 21

FAQ

What is the difference between GS1-128 and Code 128?

GS1-128 is a restricted implementation of Code 128. It always starts with an FNC1 character and uses Application Identifiers to structure the data. Plain Code 128 can encode any arbitrary string without these rules.

Why does my GTIN need to be 14 digits?

AI(01) requires a GTIN-14. If you have a 13-digit EAN or 12-digit UPC, pad it with leading zeros to reach 14 digits before entering it into the gs1-128 barcode generator. The last digit must be a correct GS1 check digit, and the tool shows the expected one if it is not.

What is FNC1 and why is it important?

FNC1 is a special non-printable character. Placed at the start of the barcode, it tells the scanner to interpret the data according to GS1 rules. Between variable-length fields, it acts as a separator so the scanner knows where one field ends and the next begins.

Can I print the generated SVG on a physical label?

Yes. SVG is a vector format that scales without losing quality. Check the GS1 General Specifications for the minimum bar width (X-dimension) for your application; GS1-128 labels are commonly printed with an X-dimension of at least 0.25 mm, and your print process needs to hold that width reliably.

Does this tool upload my product data to a server?

No. The entire gs1-128 barcode generator runs in your browser. Your GTIN, batch numbers and serial numbers never leave your device.

Which other barcode formats does Xerobit support?

Xerobit offers tools for many formats including EAN-13, ITF-14, ISBN and Codabar.