Documentation
¶
Overview ¶
Package gs1 parses and validates GS1 Application Identifier element strings as produced by barcode scanners reading GS1-128, GS1 DataMatrix, GS1 QR Code and GS1 DataBar symbols.
The package is dependency-free, allocation-conscious, and designed for the data-capture edge: point-of-care dispensing, warehouse receiving, and pharmaceutical traceability systems where scanner output is noisy and throughput matters.
Terminology ¶
An Application Identifier (AI) is a two- to four-digit prefix that declares the meaning and format of the data that follows it, as defined in the GS1 General Specifications. A sequence of AI/value pairs is an element string. Variable-length fields are terminated by the FNC1 character, which scanners transmit as ASCII 29 (Group Separator).
Parsing ¶
Parse accepts raw scanner output, bracketed human-readable form, and AIM symbology identifiers:
b, err := gs1.Parse("]d20104150000021126172506302112345ABC\x1D10LOT42X")
if err != nil {
return err
}
fmt.Println(b.GTIN(), b.Lot(), b.SerialNumber())
ParseInto reuses a caller-owned Barcode for zero-allocation parsing in hot loops. Each goroutine must own its Barcode.
Validation ¶
Parsing checks structure only. ValidateGTIN verifies the modulo-10 check digit, ParseDate validates YYMMDD dates, and Regulator profiles check that the AIs mandated by a national pharmaceutical regulator are present.
Trademark ¶
GS1 is a registered trademark of GS1 AISBL. This project is an independent implementation of publicly available specifications and is not affiliated with or endorsed by GS1.
Index ¶
- Variables
- func ComputeGTINCheckDigit(partial string) (byte, error)
- func ExpandUPCE(upce string) (string, error)
- func ParseDate(yymmdd string) (time.Time, error)
- func ParseDateRaw(yymmdd string) (string, error)
- func ParseDateWithOptions(yymmdd string, opts DateOptions) (time.Time, error)
- func ParseInto(input string, b *Barcode) error
- func ValidateGTIN(gtin string) error
- type AI
- type Barcode
- func (b Barcode) BestBeforeDate() (time.Time, error)
- func (b Barcode) Count() string
- func (b Barcode) ExpirationDate() (time.Time, error)
- func (b Barcode) GTIN() string
- func (b Barcode) Get(ai string) (string, bool)
- func (b Barcode) Lot() string
- func (b Barcode) ProductionDate() (time.Time, error)
- func (b *Barcode) Reset()
- func (b Barcode) SSCC() string
- func (b Barcode) SerialNumber() string
- func (b Barcode) ValidateANMAT() error
- func (b Barcode) ValidateANVISA() error
- func (b Barcode) ValidateCOFEPRIS() error
- func (b Barcode) ValidateSNFA() error
- type DateFormat
- type DateOptions
- type DayZeroPolicy
- type Element
- type Regulator
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ANVISA — Brazil (RDC 157/2017, SNCM). Requires GTIN + expiry + lot + serial. ANVISA = Regulator{Name: "ANVISA", Country: "BR", RequiredAIs: []string{"01", "17", "10", "21"}} // ANMAT — Argentina (Disposición 3683/2011, SNT). Requires GTIN + expiry + lot + serial. ANMAT = Regulator{Name: "ANMAT", Country: "AR", RequiredAIs: []string{"01", "17", "10", "21"}} // SNFA — Chile (ISP/MINSAL). Requires GTIN + expiry + lot. SNFA = Regulator{Name: "SNFA", Country: "CL", RequiredAIs: []string{"01", "17", "10"}} // COFEPRIS — Mexico. Requires GTIN + expiry + lot. COFEPRIS = Regulator{Name: "COFEPRIS", Country: "MX", RequiredAIs: []string{"01", "17", "10"}} )
LATAM pharmaceutical regulators and their required AIs.
var ErrEmptyInput = errors.New("gs1: empty input")
ErrEmptyInput indicates that the input string is empty or contains only whitespace.
var ErrInvalidCheckDigit = errors.New("gs1: invalid check digit")
ErrInvalidCheckDigit indicates that a GTIN's modulo-10 check digit does not match.
var ErrInvalidData = errors.New("gs1: invalid data")
ErrInvalidData indicates that field data violates the AI's type or length constraints.
var ErrInvalidDate = errors.New("gs1: invalid date")
ErrInvalidDate indicates that a YYMMDD date field contains an impossible date.
var ErrMissingRequiredAI = errors.New("gs1: missing required AI")
ErrMissingRequiredAI indicates that a barcode is missing an AI required by a regulator.
var ErrTruncatedData = errors.New("gs1: truncated data")
ErrTruncatedData indicates that the input ended before a fixed-length field was fully consumed.
var ErrUnknownAI = errors.New("gs1: unknown application identifier")
ErrUnknownAI indicates that the parser encountered an unrecognized Application Identifier.
Functions ¶
func ComputeGTINCheckDigit ¶
ComputeGTINCheckDigit computes the GS1 modulo-10 check digit for a partial GTIN (all digits except the check digit). Returns the check digit as a byte ('0'-'9').
func ExpandUPCE ¶
ExpandUPCE expands a 6-digit UPC-E code (without check digit) or an 8-digit UPC-E (with number system and check digit) to a 12-digit UPC-A. The input must be 6 or 8 digits.
func ParseDate ¶
ParseDate parses a 6-digit YYMMDD date string as used in GS1 barcodes. Years map to 2000-2099. Day 00 means the last day of the specified month (deprecated since 2025 but supported for backward compatibility).
func ParseDateRaw ¶
ParseDateRaw validates a YYMMDD string and returns it as-is without converting to time.Time. Useful when the caller wants the raw GS1 value.
func ParseDateWithOptions ¶
func ParseDateWithOptions(yymmdd string, opts DateOptions) (time.Time, error)
ParseDateWithOptions parses a YYMMDD date with configurable day-zero policy. When opts.Format is DateFormatRaw, the returned time is zero-valued; use ParseDateRaw instead for a string result.
Example ¶
package main
import (
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
last, _ := gs1.ParseDate("250200")
first, _ := gs1.ParseDateWithOptions("250200", gs1.DateOptions{DayZero: gs1.DayZeroFirstDay})
fmt.Println(last.Format("2006-01-02"), first.Format("2006-01-02"))
}
Output: 2025-02-28 2025-02-01
func ParseInto ¶
ParseInto parses a GS1 barcode string into an existing Barcode, reusing its allocated memory. Call b.Reset() before reuse to clear previous data. Each goroutine must use its own Barcode.
Example ¶
package main
import (
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
scans := []string{
"0104150000021126172506301012345",
"010415000002112617251231\x1D10LOT2",
}
var b gs1.Barcode
for _, s := range scans {
b.Reset()
if err := gs1.ParseInto(s, &b); err != nil {
fmt.Println("error:", err)
continue
}
fmt.Println(b.GTIN(), b.Lot())
}
}
Output: 04150000021126 12345 04150000021126 LOT2
func ValidateGTIN ¶
ValidateGTIN validates the modulo-10 check digit of a GTIN string. It accepts GTIN-8, GTIN-12, GTIN-13, and GTIN-14.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
fmt.Println(gs1.ValidateGTIN("04150000021126"))
err := gs1.ValidateGTIN("04150000021127")
fmt.Println(errors.Is(err, gs1.ErrInvalidCheckDigit))
}
Output: <nil> true
Types ¶
type AI ¶
type AI struct {
Code string // AI code, e.g. "01", "10", "3102"
Name string // data title, e.g. "GTIN", "Batch/Lot"
Format string // format specifier, e.g. "N14", "X..20"
}
AI describes a GS1 Application Identifier as listed in the GS1 General Specifications. Format uses GS1 Syntax Dictionary notation: "N14" is exactly 14 digits, "X..20" is up to 20 characters of any type.
func LookupAI ¶
LookupAI returns the specification for an Application Identifier code such as "01" or "3102". The boolean is false for codes this package does not recognize.
Example ¶
package main
import (
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
ai, ok := gs1.LookupAI("3102")
fmt.Println(ok, ai.Name, ai.Format)
}
Output: true Net Weight kg N6
type Barcode ¶
type Barcode struct {
Raw string // original input string
Elements []Element // parsed AI-value pairs in scan order
}
Barcode represents a fully parsed GS1 barcode (GS1-128 or DataMatrix).
func Parse ¶
Parse parses a GS1 barcode string (GS1-128 or DataMatrix scanner output) into a Barcode with typed elements. It handles AIM symbology identifiers (e.g., ]C1, ]d2), FNC1 separators (ASCII 29), and bracket notation (e.g., "(01)04150000021126(17)250630").
Example ¶
package main
import (
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
b, err := gs1.Parse("0104150000021126172506302112345ABC\x1D10LOT42X")
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("GTIN: ", b.GTIN())
fmt.Println("Lot: ", b.Lot())
fmt.Println("Serial:", b.SerialNumber())
exp, _ := b.ExpirationDate()
fmt.Println("Expiry:", exp.Format("2006-01-02"))
}
Output: GTIN: 04150000021126 Lot: LOT42X Serial: 12345ABC Expiry: 2025-06-30
Example (BracketNotation) ¶
package main
import (
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
b, _ := gs1.Parse("(01)04150000021126(17)250630(10)ABC123")
for _, e := range b.Elements {
ai, _ := gs1.LookupAI(e.AI)
fmt.Printf("(%s) %-16s %s\n", e.AI, ai.Name, e.Value)
}
}
Output: (01) GTIN 04150000021126 (17) Expiration Date 250630 (10) Batch/Lot ABC123
func (Barcode) BestBeforeDate ¶
BestBeforeDate returns the parsed best-before date (AI 15).
func (Barcode) ExpirationDate ¶
ExpirationDate returns the parsed expiration date (AI 17).
func (Barcode) Get ¶
Get returns the value for the given AI code and whether it was found. If the AI appears multiple times, the first occurrence is returned.
func (Barcode) ProductionDate ¶
ProductionDate returns the parsed production date (AI 11).
func (*Barcode) Reset ¶
func (b *Barcode) Reset()
Reset clears a Barcode for reuse, retaining allocated memory.
func (Barcode) SerialNumber ¶
SerialNumber returns the serial number (AI 21), or "" if not present.
func (Barcode) ValidateANMAT ¶
ValidateANMAT checks compliance with Argentina's ANMAT traceability requirements.
func (Barcode) ValidateANVISA ¶
ValidateANVISA checks compliance with Brazil's ANVISA traceability requirements.
func (Barcode) ValidateCOFEPRIS ¶
ValidateCOFEPRIS checks compliance with Mexico's COFEPRIS traceability requirements.
func (Barcode) ValidateSNFA ¶
ValidateSNFA checks compliance with Chile's SNFA traceability requirements.
type DateFormat ¶
type DateFormat int
DateFormat controls the output style for date fields.
const ( // DateFormatTime returns parsed time.Time values (default). DateFormatTime DateFormat = iota // DateFormatRaw returns the raw YYMMDD string without parsing to time.Time. DateFormatRaw )
type DateOptions ¶
type DateOptions struct {
DayZero DayZeroPolicy
Format DateFormat
}
DateOptions configures date parsing behavior.
type DayZeroPolicy ¶
type DayZeroPolicy int
DayZeroPolicy controls how day=00 in YYMMDD dates is resolved.
const ( // DayZeroLastDay resolves day 00 to the last day of the month (GS1 default). DayZeroLastDay DayZeroPolicy = iota // DayZeroFirstDay resolves day 00 to the first day of the month. DayZeroFirstDay )
type Element ¶
type Element struct {
AI string // application identifier code, e.g., "01"
Value string // raw data value
}
Element represents a single AI-value pair extracted from a GS1 barcode.
type Regulator ¶
type Regulator struct {
Name string // regulatory body name, e.g., "ANVISA"
Country string // ISO 3166-1 alpha-2 country code
RequiredAIs []string // AI codes that must be present in compliant barcodes
}
Regulator represents a pharmaceutical regulatory body that mandates specific GS1 Application Identifiers for drug traceability.
func (Regulator) Validate ¶
Validate checks that the barcode contains all Application Identifiers required by this regulator. Returns nil if compliant, or an error listing the first missing AI.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/galenzo17/gs1-go"
)
func main() {
b, _ := gs1.Parse("01041500000211261725063010LOT42X")
fmt.Println(gs1.COFEPRIS.Validate(b))
err := gs1.ANVISA.Validate(b)
fmt.Println(errors.Is(err, gs1.ErrMissingRequiredAI), err)
}
Output: <nil> true gs1: missing required AI: ANVISA requires AI (21)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
gs1
command
Command gs1 parses GS1 Application Identifier element strings from the command line or from a stream of scanner output on stdin.
|
Command gs1 parses GS1 Application Identifier element strings from the command line or from a stream of scanner output on stdin. |
|
gs1-wasm
command
|