GS1.Code (gs1_barcode v0.1.2)
View SourceUtilities for detecting, validating, creating and normalizing GS1 codes.
Handles GTIN-8 (EAN-8 symbology), GTIN-12 (UPC-A symbology), GTIN-13 (GLN, EAN-13 symbology), GTIN-14 (ITF-14 symbology) and SSCC-18.
Summary
Functions
Generates a valid SSCC (Serial Shipping Container Code) from the Extension Digit, GS1 Company Prefix (GCP), and Serial Reference.
Bang version of build_sscc/3. Raises ArgumentError if invalid arguments passed.
Lookups country (MO) based on the code prefix.
Returns nil non-country ranges and for GTIN-8 as they use a distinct prefix list.
Checks if valid code is a coupon. Detects various coupon formats, including global coupons and restricted circulation coupons often used within specific geographic regions.
Checks if valid code is in range reserved for demonstration or testing.
Detects valid GS1 code and returns type.
Bang version of detect/1. Raises an ArgumentError if the code is invalid .
Generates a complete GS1 code GTIN-8,12,13 from integer key. For GTIN-14 and SSCC,
use the corresponding dedicated functions.
Bang version of generate/2. Raises an ArgumentError if the code cannot be
generated (e.g., key is out of bounds, invalid type, or attempts to generate SSCC/GTIN-14).
Checks if valid code is an ISBN (International Standard Book Number).
Checks if valid code is an ISSN (International Standard Serial Number).
Returns payload (part without check digit) of valid code.
Bang version of payload/1. Raises ArgumentError if code is invalid (detect error).
Lookups usage range of the valid code.
Checks if the valid code belongs to a Restricted Circulation Number (RCN) range.
Checks if valid code is a Refund Receipt.
Normalizes valid GTIN-8 to a GTIN-12 Returns error if the input is not a valid GTIN or cannot be normalized to this dimension.
Bang version of to_gtin12/1. Raises ArgumentError if the code cannot be detected or normalized.
Normalizes valid GTIN-8,12 to a GTIN-13.
Bang version of to_gtin13/1. Raises ArgumentError if the code cannot be detected or normalized.
Normalizes a valid GTIN-8, 12, or 13 to a GTIN-14 with a given Packaging Level Indicator (PLI).
Bang version of to_gtin14/1. Raises ArgumentError if the code cannot be detected or normalized.
Casts a valid GS1 GTIN code to its pure base integer representation by stripping necessary prefixes and check digit.
Bang version of to_key/1. Raises ArgumentError if the code cannot be detected or normalized.
Types
@type code_type() :: :gtin8 | :gtin12 | :gtin13 | :gtin14 | :sscc
Detected code type.
@type detect_error() :: :invalid_length | :invalid_input | :invalid_digit_or_checksum
Detect error reason.
@type generate_error() ::
:invalid_key
| :invalid_type
| :key_out_of_bounds
| :use_to_gtin14
| :use_build_sscc
Generate error reason.
@type normalize_error() :: :cannot_normalize | :sscc_has_no_product_id
Normalize error reason.
Functions
@spec build_sscc(non_neg_integer() | char(), String.t(), String.t()) :: {:error, :gcp_or_serial_too_long | :invalid} | {:ok, String.t()}
Generates a valid SSCC (Serial Shipping Container Code) from the Extension Digit, GS1 Company Prefix (GCP), and Serial Reference.
SSCC is an 18-digit number used to identify logistics units, with structure:
- Extension Digit: 1 digit (0-9).
- GS1 Company Prefix: variable length.
- Serial Reference: variable length (padded with leading zeros if needed).
- Check Digit: 1 digit.
Function ensures that the combined length of GCP and Serial doesn't exceeds 16 digits,
and returns an error if the provided serial is too long to fit within the remaining
space allowed by the GCP.
Examples
iex> GS1.Code.build_sscc(1, "4006381", "12345")
{:ok, "140063810000123454"}
# Accepts Extension Digit as char or integer
iex> GS1.Code.build_sscc(?0, "4006381", "12345")
{:ok, "040063810000123457"}
iex> GS1.Code.build_sscc(1, "1234567890123456", "1")
{:error, :gcp_or_serial_too_long}
@spec build_sscc!(non_neg_integer() | char(), String.t(), String.t()) :: String.t()
Bang version of build_sscc/3. Raises ArgumentError if invalid arguments passed.
Examples
iex> GS1.Code.build_sscc!(1, "4006381", "12345")
"140063810000123454"
@spec country(String.t()) :: GS1.CompanyPrefix.country_mo() | {:error, detect_error()}
Lookups country (MO) based on the code prefix.
Returns nil non-country ranges and for GTIN-8 as they use a distinct prefix list.
Examples
iex> GS1.Code.country("4006381333931")
[{"Germany", "DE", "DEU", "276"}]
Checks if valid code is a coupon. Detects various coupon formats, including global coupons and restricted circulation coupons often used within specific geographic regions.
Examples
iex> GS1.Code.coupon?("9812345678902")
true
Checks if valid code is in range reserved for demonstration or testing.
Examples
iex> GS1.Code.demo?("9529999199997")
true
@spec detect(String.t()) :: {:ok, code_type()} | {:error, detect_error()}
Detects valid GS1 code and returns type.
Examples
iex> GS1.Code.detect("4006381333931")
{:ok, :gtin13}
iex> GS1.Code.detect("123")
{:error, :invalid_length}
Bang version of detect/1. Raises an ArgumentError if the code is invalid .
Examples
iex> GS1.Code.detect!("4006381333931")
:gtin13
iex> GS1.Code.detect!("123")
** (ArgumentError) invalid_length
@spec generate(code_type(), pos_integer()) :: {:error, generate_error()} | {:ok, String.t()}
Generates a complete GS1 code GTIN-8,12,13 from integer key. For GTIN-14 and SSCC,
use the corresponding dedicated functions.
This function is primarily intended for restoring from key representation or generating codes in RCN (Restricted Circulation Number) ranges (e.g., prefixes 02, 04, 20-29) and other private ranges, which are used for internal company purposes, variable measure items, or region-specific applications.
Standard GTINs for commercial use must be obtained from local GS1 MO. This function does not validate if the generated code falls within an allocated prefix range.
Returns {:ok, code} on success, or {:error, generate_error()} on failure.
Examples
iex> GS1.Code.generate(:gtin13, 200000000034)
{:ok, "2000000000343"}
iex> GS1.Code.generate(:gtin14, 200000000034)
{:error, :use_to_gtin14}
@spec generate!(code_type(), pos_integer()) :: String.t()
Bang version of generate/2. Raises an ArgumentError if the code cannot be
generated (e.g., key is out of bounds, invalid type, or attempts to generate SSCC/GTIN-14).
Examples
iex> GS1.Code.generate!(:gtin13, 200000000034)
"2000000000343"
iex> GS1.Code.generate!(:gtin14, 200000000034)
** (ArgumentError) use_to_gtin14
Checks if valid code is an ISBN (International Standard Book Number).
Examples
iex> GS1.Code.isbn?("9783161484100")
true
Checks if valid code is an ISSN (International Standard Serial Number).
Examples
iex> GS1.Code.issn?("9771234567003")
true
@spec payload(String.t()) :: {:ok, String.t()} | {:error, detect_error()}
Returns payload (part without check digit) of valid code.
Examples
iex> GS1.Code.payload("4006381333931")
{:ok, "400638133393"}
Bang version of payload/1. Raises ArgumentError if code is invalid (detect error).
Examples
iex> GS1.Code.payload!("4006381333931")
"400638133393"
@spec range(String.t()) :: {:ok, GS1.CompanyPrefix.range_type()} | {:error, detect_error()}
Lookups usage range of the valid code.
Returns {:ok, range_type} if found, {:ok, nil} if code valid but not in special range,
or {:error, reason} if the code detection failed
Examples
iex> GS1.Code.range("2000000000039")
{:ok, :rcn}
iex> GS1.Code.range("9781449369996")
{:ok, :isbn}
iex> GS1.Code.range("4006381333931") # GTIN for product with country code prefix
{:ok, nil}
Checks if the valid code belongs to a Restricted Circulation Number (RCN) range.
RCNs are used for internal purposes (e.g., variable measure items like meat/produce sold by weight, or internal company codes) and should not be used in open trade.
Examples
iex> GS1.Code.rcn?("2001234567893")
true
iex> GS1.Code.rcn?("4006381333931") # Standard trade item
false
Checks if valid code is a Refund Receipt.
Examples
iex> GS1.Code.refund?("9800004500008")
true
@spec to_gtin12(String.t()) :: {:ok, String.t()} | {:error, detect_error() | normalize_error()}
Normalizes valid GTIN-8 to a GTIN-12 Returns error if the input is not a valid GTIN or cannot be normalized to this dimension.
Examples
iex> GS1.Code.to_gtin12("40052441")
{:ok, "000040052441"}
Bang version of to_gtin12/1. Raises ArgumentError if the code cannot be detected or normalized.
Examples
iex> GS1.Code.to_gtin12!("40052441")
"000040052441"
@spec to_gtin13(String.t()) :: {:ok, String.t()} | {:error, detect_error() | normalize_error()}
Normalizes valid GTIN-8,12 to a GTIN-13.
GTIN-14 is reduced to GTIN-13 by stripping 1-digit Packaging Level Indicator (PLI) and payload with check digit calculation. No additional PLI logic check applied.
Returns error if the input is not a valid GTIN or cannot be normalized to this dimension.
Examples
iex> GS1.Code.to_gtin13("12345670")
{:ok, "0000012345670"}
# GTIN-14 is reduced to GTIN-13 (payload + new check digit calculated)
iex> GS1.Code.to_gtin13("10123456789019")
{:ok, "0123456789012"}
Bang version of to_gtin13/1. Raises ArgumentError if the code cannot be detected or normalized.
Examples
iex> GS1.Code.to_gtin13!("12345670")
"0000012345670"
@spec to_gtin14(non_neg_integer() | char(), String.t()) :: {:ok, String.t()} | {:error, detect_error() | normalize_error()}
Normalizes a valid GTIN-8, 12, or 13 to a GTIN-14 with a given Packaging Level Indicator (PLI).
A PLI can be an int [0, 9] or its character representation.
- PLI 0: Simply pads the input to 14 digits (preserves existing check digit).
- PLI 1-9: Constructs a new hierarchical code and recalculates the Check Digit.
Returns error if the input is not a valid GTIN or cannot be normalized.
Examples
iex> GS1.Code.to_gtin14(1, "4006381333931")
{:ok, "14006381333938"}
iex> GS1.Code.to_gtin14(0, "4006381333931")
{:ok, "04006381333931"}
@spec to_gtin14!(non_neg_integer() | char(), String.t()) :: String.t()
Bang version of to_gtin14/1. Raises ArgumentError if the code cannot be detected or normalized.
Examples
iex> GS1.Code.to_gtin14!(0, "4006381333931")
"04006381333931"
@spec to_key(String.t()) :: {:error, :invalid_key_type | detect_error()} | {:ok, pos_integer()}
Casts a valid GS1 GTIN code to its pure base integer representation by stripping necessary prefixes and check digit.
This representation is the core identification number suitable for storage in a database or use as a unique int key for data lookup.
Logic for extracting the base int is dependent on the detected code type:
- SSCC: cannot be reduced to a key because it doesn't contains product GTIN.
Returns
{:error, :invalid_key_type}. - GTIN-14: base number is derived by stripping both the first char Indicator (PLI) and trailing check digit (last character).
- Other GTIN codes: base number is derived by stripping only the trailing Check Digit. The remaining digits are converted to an int.
Examples
iex> GS1.Code.to_key("11234567890125")
{:ok, 123456789012} # strips '1' (Indicator) and '8' (Check Digit)
iex> GS1.Code.to_key("1234567890128")
{:ok, 123456789012} # strips '8' (Check Digit)
iex> GS1.Code.to_key("012345679999999997") # SSCC cannot be converted
{:error, :invalid_key_type}
@spec to_key!(String.t()) :: pos_integer()
Bang version of to_key/1. Raises ArgumentError if the code cannot be detected or normalized.
Examples
iex> GS1.Code.to_key!("1234567890128")
123456789012