# GS1-128

> Source: https://docs.barcoder.ai/docs/standards/gs1-128
> research date 2026-05-30 · extracted at 2026-10-03
> Publisher: Barcoder — encyclopedia of QR, barcode and payment-code standards

Specifications:
- [GS1-128 — GS1 General Specifications](https://www.gs1.org/standards/barcodes/gs1-128)
- [ISO/IEC 15417:2007 — Code 128 bar code symbology specification](https://www.iso.org/standard/43896.html)
- [GS1-128 — Wikipedia](https://en.wikipedia.org/wiki/GS1-128)

# GS1-128

## Overview

**GS1-128** (formerly **UCC/EAN-128**) is an application profile of the [Code 128](https://docs.barcoder.ai/docs/standards/code-128) barcode symbology, defined and governed by the **GS1 General Specifications** <sup>[1][1]</sup>. It is not a separate symbology: it uses the same bar/space encoding as Code 128 (standardised as **ISO/IEC 15417:2007** <sup>[2][2]</sup>), but reserves the **FNC1** function character — placed immediately after the start character — as a flag that the symbol carries **GS1 Application Identifier (AI)** data <sup>[3][3]</sup>. This single structural rule turns a generic Code 128 symbol into a self-describing, machine-parseable data carrier for the supply chain.

GS1-128 is **the global standard for supply-chain shipping and packaging identification** — pallet and case labels, the Serial Shipping Container Code (SSCC), pharmaceutical-distribution outer packaging, and healthcare logistics all rely on it <sup>[1][1]</sup>. Its defining feature is that one symbol can concatenate several AI element strings — for example a GTIN, a use-by date, and a batch number — into a single, scannable string of structured data.

## History

**1989 — UCC/EAN-128 publication** <sup>[3][3]</sup>: The **Uniform Code Council (UCC)** (the US numbering authority) and the **European Article Numbering association (EAN International)** jointly published a profile of Code 128 for structured supply-chain data. The profile defined how to embed GS1 Application Identifiers — GTINs, batch numbers, dates, weights, and other logistics fields — inside a Code 128 symbol, using the FNC1 character to mark and delimit them. The result was named **UCC/EAN-128**.

**2005 — Rebrand to GS1-128** <sup>[3][3]</sup>: When UCC and EAN International merged into **GS1** (Global Standards One), UCC/EAN-128 was renamed **GS1-128**. The technical specification was unchanged — only the name and governing body changed. The standard is now maintained as part of the **GS1 General Specifications** <sup>[1][1]</sup>.

**Underlying symbology lineage** <sup>[2][2], [4][4]</sup>: The base symbology, Code 128, was developed by Computer Identics Corporation in 1981 and standardised internationally as ISO/IEC 15417:2007. GS1-128 inherits that bar/space encoding, the three character subsets (A, B, C), and the modulo-103 check character; it adds only the GS1 data-formatting conventions on top.

## Technical specification

GS1-128 is a **structured-data profile of Code 128** <sup>[1][1], [3][3], [4][4]</sup>:

| Parameter | Value |
|---|---|
| Base symbology | Code 128 (ISO/IEC 15417:2007) |
| Symbology family | 1D linear |
| Distinguishing feature | **FNC1 immediately after the start character** |
| Data model | GS1 Application Identifiers (AIs) + element strings |
| Character subsets | A, B, C (inherited from Code 128) |
| Field separator | FNC1 (used after variable-length AI fields) |
| Check character | Modulo-103 (inherited from Code 128) |
| Variable length | Yes — no fixed code length |
| Practical max data | Up to 48 encoded characters per symbol (GS1 limit) <sup>[5][5]</sup> |
| Quiet zone | 10 × module width on each side (minimum) |
| Bidirectional reading | Yes |

**The FNC1 rule** <sup>[1][1], [3][3]</sup>: A Code 128 symbol becomes a GS1-128 symbol when the **FNC1** function character is placed in the first position after the start code. Scanners that decode this leading FNC1 transmit it as the symbology identifier `]C1`, signalling to the receiving application that the data is GS1-formatted and should be parsed by Application Identifier rather than treated as free text.

**Application Identifiers (AIs)** <sup>[1][1], [6][6]</sup>: An AI is a numeric prefix (2–4 digits) that defines the meaning and format of the data field that follows. Common AIs include:

| AI | Meaning | Format |
|---|---|---|
| **(00)** | SSCC — Serial Shipping Container Code | 18 digits, fixed |
| **(01)** | GTIN (trade item number, GTIN-14 form) | 14 digits, fixed |
| **(10)** | Batch / lot number | up to 20 alphanumeric, variable |
| **(11)** | Production date | 6 digits YYMMDD, fixed |
| **(17)** | Expiration / use-by date | 6 digits YYMMDD, fixed |
| **(21)** | Serial number | up to 20 alphanumeric, variable |
| **(310n)** | Net weight (kg) | 6 digits + decimal indicator |
| **(37)** | Count of trade items | variable |

**Concatenation and the separator role of FNC1** <sup>[1][1], [3][3], [6][6]</sup>: A single GS1-128 symbol can carry multiple AI element strings back-to-back. Fields with a **predefined fixed length** (such as `(01)` GTIN-14 or `(17)` date) need no separator — the scanner knows where they end. Fields of **variable length** (such as `(10)` batch or `(21)` serial) must be terminated by an **FNC1** character when another AI follows, so the parser can find the boundary. This is why FNC1 plays a dual role in GS1-128: a flag in the first position, and a field delimiter thereafter.

**Worked example** — the payload `(01)03453120000011(17)191125(10)ABCD1234` encodes a GTIN-14 (`(01)`, fixed 14 digits), a use-by date of 25 November 2019 (`(17)`, fixed YYMMDD), and batch `ABCD1234` (`(10)`, variable). Because `(10)` is the last field, no trailing FNC1 separator is required; if another AI followed `(10)`, an FNC1 would be inserted after the batch value. The parentheses are a **human-readable convention only** — they are printed in the text line beneath the bars but are **not encoded** in the barcode itself.

## Use cases

GS1-128 is the dominant 1D carrier for **structured supply-chain, logistics, and healthcare data** <sup>[1][1], [3][3]</sup>:

- **Logistics unit labels (SSCC)** — every commercial pallet or shipping unit moved through modern distribution carries a GS1 logistics label whose primary barcode is a GS1-128 encoding the **SSCC `(00)`**. This is the canonical GS1-128 deployment.
- **Case and carton labelling** — outer cases use GS1-128 to combine GTIN `(01)`, batch `(10)`, and expiry `(17)` so a single scan captures product, lot, and date for traceability.
- **Pharmaceutical distribution** — bulk drug-distribution outer packaging uses GS1-128 (with GTIN, batch, expiry, and serial AIs) alongside [Data Matrix](https://docs.barcoder.ai/docs/standards/data-matrix)/GS1 DataMatrix on the consumer-facing inner packs.
- **Healthcare and UDI** — medical-device and healthcare logistics use GS1-128 to carry the Unique Device Identifier (UDI) element strings on larger packaging where linear space is available.
- **Variable-measure retail and food** — `(310n)` net-weight and date AIs let GS1-128 label variable-weight goods (meat, produce) for distribution.
- **Fresh-food and cold-chain traceability** — batch/lot `(10)` plus production `(11)` and expiry `(17)` dates enable recall management and shelf-life control.

**Why GS1-128 is chosen for these contexts** <sup>[1][1], [3][3]</sup>:
- It encodes the standardised AI data structure that downstream warehouse, ERP, and EDI systems already understand.
- It rides on Code 128, so **every existing supply-chain scanner** reads it with no new hardware.
- Multiple data fields fit in one symbol, and multiple symbols fit on one logistics label.
- It is royalty-free, inheriting Code 128's public-domain status.

## Implementations

Because GS1-128 is Code 128 plus formatting rules, **any Code 128 encoder/decoder can produce or read the bars**; GS1-128 support specifically means the library understands AI formatting and FNC1 placement <sup>[7][7]</sup>:

- **JavaScript** — [metafloor/bwip-js][7] — ~2 400★, active 2026. Barcode Writer in Pure JavaScript; supports GS1-128 (and GS1-128 Composite) with AI parsing in browser and Node.js.
- **C / C++** — **Zint** (`zint/zint`, `libzint`) — comprehensive open-source generator written in C with explicit GS1-128 (and HIBC) support and AI checking.
- **Java + many ports** — [zxing/zxing][8] — 34 000★, active 2025. Decodes Code 128 / GS1-128 (returns the `]C1` symbology identifier and FNC1 markers) alongside QR, PDF417, Data Matrix.
- **Python** — `python-barcode`, `treepoem` (wraps Barcode Writer in Pure PostScript, which has full GS1-128 AI support).
- **PHP** — `picqer/php-barcode-generator`.
- **Thermal printers** — Zebra (ZPL), Honeywell, SATO, and TSC label printers generate GS1-128 directly from their command languages, including FNC1 insertion.
- **Industrial scanners** — every commercial 1D scanner (Cognex, Datalogic, Honeywell, Zebra, SICK) decodes GS1-128 and most can be configured to parse and re-transmit the AI fields.

**Open standards documentation**:
- [GS1 General Specifications][1] — define the GS1-128 profile, the FNC1 rule, and the Application Identifier registry.
- [ISO/IEC 15417:2007][2] — the canonical specification of the underlying Code 128 symbology.

## Comparison

**vs. [Code 128](https://docs.barcoder.ai/docs/standards/code-128) (the base symbology)** — Code 128 is the general-purpose symbology that can encode any of the 128 ASCII characters. GS1-128 is a **constrained application of it**: same bars, same check digit, but a mandatory leading FNC1 and a strict GS1 AI data model. Choose plain Code 128 for arbitrary alphanumeric strings (tracking numbers, internal IDs); choose GS1-128 when the data must be standardised AI element strings that GS1-aware systems will parse.

**vs. [Data Matrix](https://docs.barcoder.ai/docs/standards/data-matrix) (GS1 DataMatrix)** — GS1 DataMatrix encodes the **same** GS1 Application Identifier structure, but in a 2D matrix. The 2D version is far smaller and fits on a single consumer drug-carton face, but needs a 2D-capable imager. GS1-128 dominates pallets and outer packaging where horizontal label space is plentiful and 1D laser scanners are entrenched; GS1 DataMatrix dominates retail consumer packaging and pharmaceutical inner packs where space is scarce.

**vs. [GS1 DataBar](https://docs.barcoder.ai/docs/standards/gs1-databar)** — GS1 DataBar (formerly RSS) is a compact 1D family that also carries GS1 AIs and is targeted at small retail items (loose produce, coupons) scanned at point of sale. GS1-128 is the logistics-and-distribution carrier — larger, higher capacity, multiple AIs per symbol — while GS1 DataBar is the small-footprint POS carrier. Both encode the same AI data model.

**vs. [ITF](https://docs.barcoder.ai/docs/standards/itf) (ITF-14)** — ITF-14 (Interleaved 2 of 5) is the GS1 outer-carton variant restricted to a single 14-digit GTIN. GS1-128 is far more flexible — it can add batch, dates, weights, and serials in the same symbol — but consumes more printable width and is more sensitive to print quality than the robust ITF-14.

## Fun facts

The **parentheses in `(01)`, `(17)`, `(10)` are never encoded in the barcode** <sup>[1][1], [6][6]</sup> — they appear only in the human-readable text line to delimit Application Identifiers for the eye. The scanner reconstructs field boundaries entirely from the AI registry (fixed-length AIs) and FNC1 separators (after variable-length AIs). A common integration bug is software that tries to transmit or strip the literal parentheses.

**FNC1 does double duty** in GS1-128 <sup>[3][3]</sup>: the same function character means "this is GS1 data" when it appears in the first position, and "this variable-length field ends here" when it appears between two AI element strings. No other Code 128 profile loads a single control character with two distinct semantic roles.

The name changed but **not a single bar did**: when UCC/EAN-128 became GS1-128 in 2005, the rebrand was purely organisational — the merger of UCC and EAN into GS1 — and existing symbols, scanners, and labels remained fully valid and unchanged <sup>[3][3]</sup>.

## Status

**Active, foundational, and ubiquitous** in the supply chain <sup>[1][1], [3][3]</sup>:

- **GS1 General Specifications** maintain GS1-128 as a current, core barcode standard.
- The underlying **ISO/IEC 15417:2007** Code 128 spec has been stable for nearly two decades.
- **Universal scanner support** — inherited from Code 128 — across every industrial 1D scanner.
- **Public domain / royalty-free**, like Code 128.

**Strategic context**:
- GS1 maintains GS1-128 in parallel with **GS1 DataMatrix** and **GS1 DataBar**; all three carry the same AI data model, and the choice is driven by available label space and existing scanner infrastructure rather than by data capability.
- GS1-128's grip on the **logistics unit label (SSCC), case labelling, and distribution-level healthcare packaging** remains unchallenged, even as 2D codes encroach on consumer-facing and small-footprint applications.
- No deprecation is planned.

## Sources

[1]: https://www.gs1.org/standards/barcodes/gs1-128
[2]: https://www.iso.org/standard/43896.html
[3]: https://en.wikipedia.org/wiki/GS1-128
[4]: https://en.wikipedia.org/wiki/Code_128
[5]: https://www.barcodefaq.com/1d/gs1-128/
[6]: https://www.gs1.org/standards/barcodes/application-identifiers
[7]: https://github.com/metafloor/bwip-js
[8]: https://github.com/zxing/zxing
[code-128-ref]: https://docs.barcoder.ai/source/standards/code-128
[data-matrix-ref]: https://docs.barcoder.ai/source/standards/data-matrix

1. [GS1-128 — GS1 General Specifications][1]
2. [ISO/IEC 15417:2007 — Code 128 specification][2]
3. [GS1-128 — Wikipedia][3]
4. [Code 128 — Wikipedia][4]
5. [GS1-128 barcode reference — BarcodeFAQ][5]
6. [GS1 Application Identifiers — GS1][6]
7. [metafloor/bwip-js — GitHub][7]
8. [zxing/zxing — GitHub][8]

## Deployments

Found in the following country reports (grep across `reports/countries/`):

- **IT** — [IT-italy.md](https://docs.barcoder.ai/docs/payments/IT) — GS1-128 / Code 128 used in supply-chain and retail distribution.

## Regions / aggregations not mapped to a single country

- Universal

## Deployments

Found in the following country reports (grep across `reports/countries/`):

- **IT** — [IT-italy.md](https://docs.barcoder.ai/docs/payments/IT)

## Regions / aggregations not mapped to a single country

- Universal
