GS1.Utils (gs1_barcode v0.1.2)
View SourceUtility functions for:
- GLN validation
- Converting AI data with implied decimal points into floats.
- Converting between GS1 20-digit location strings and WGS84 lat/long coordinates and vice versa.
Summary
Functions
Extracts ISO currency code and amount value from ISO AI data string containing an ISO currency code prefix followed by an amount with an implied decimal point into structured data.
Converts a AIs (like "310x", "320x", etc.) data string, which may contain an implied decimal point to float.
Converts a 20-char data string (e.g., AI "8200") to WGS84 lat, lon coords.
Decodes int X component of GS1 location string back into a WGS84 latitude.
Decodes the int Y component of GS1 location string back into a WGS84 longitude.
Validates if a code structure matches a GLN (Global Location Number). GLN is structurally identical to a GTIN-13 but relies on context.
Converts WGS84 lat/lon coords into integer representation used by GS1.
Converts WGS84 lan, lon coords to 20-char GS1 encoded string.
Functions
@spec data_iso_to_float(String.t(), any()) :: {:error, :invalid | :len_mismatch} | {:ok, String.t(), float()}
Extracts ISO currency code and amount value from ISO AI data string containing an ISO currency code prefix followed by an amount with an implied decimal point into structured data.
This function is used for AIs like "391n" where the data field consists of:
- 3-digit ISO 4217 currency code (e.g., "978" for EUR, "840" for USD)
- Amount with an implied decimal point position (
npart from AI)
See data_to_float/2 for the underlying amount conversion logic.
Parameters
data: AI data string starting with a 3-digit ISO currency code followed by the amount (e.g.,"978150"for €1.50 whendec_placesis 2).dec_places: The number of digits after the implied decimal point.
Returns
{:ok, iso_code_str, float_amount}- on success; note that ISO 4217 currency code validation is not performed.{:error, :invalid}- if the ISO code or amount cannot be parsed.{:error, :len_mismatch}- if the amount part is too short for the given decimal places.
Examples
iex> GS1.Utils.data_iso_to_float("978150", 2)
{:ok, "978", 1.5}
iex> GS1.Utils.data_iso_to_float("8401000", 0)
{:ok, "840", 1000.0}
iex> GS1.Utils.data_iso_to_float("978099", 2)
{:ok, "978", 0.99}
@spec data_to_float(String.t(), non_neg_integer()) :: {:error, :invalid | :len_mismatch} | {:ok, float()}
Converts a AIs (like "310x", "320x", etc.) data string, which may contain an implied decimal point to float.
The dec_places parameter specifies how many digits from the right of the string
represent the fractional part. See genspec: 7.8.7 Application Identifiers with implied
decimal point positions
Parameters
data: AI data part (e.g.,"3000200").dec_places: The number of digits after the implied decimal point (e.g.,3).
Returns
{:ok, float()}- if conversion is successful.{:error, :invalid}- if the resulting string cannot be parsed as a float.{:error, :len_mismatch}- if the length ofdatais less than or equal todec_places.
Examples
iex> GS1.Utils.data_to_float("3000200", 3)
{:ok, 3000.2}
Converts a 20-char data string (e.g., AI "8200") to WGS84 lat, lon coords.
Input is split into two 10-char parts:
- First 10 characters encode latitude (X).
- Second 10 characters encode longitude (Y).
The conversion logic is defined by GS1 specifications for location encoding.
Parameters
data: A 20-char binary/string containing the encoded coordinates.
Returns
{:ok, {latitude, longitude}}- where both are floats.{:error, :invalid}- if the input is not a 20-char binary or parts are invalid.
Examples
iex> GS1.Utils.string_20_to_wgs84_lat_log("02790858483015297971")
{:ok, {-62.0914152, -58.470202900000004}}
@spec to_wgs84_latitude_deg(non_neg_integer()) :: nil | float()
Decodes int X component of GS1 location string back into a WGS84 latitude.
Examples
iex> GS1.Utils.to_wgs84_latitude_deg(0279085848)
-62.0914152
@spec to_wgs84_longitude_deg(non_neg_integer()) :: nil | float()
Decodes the int Y component of GS1 location string back into a WGS84 longitude.
Examples
iex> GS1.Utils.to_wgs84_longitude_deg(3015297971)
-58.470202900000004
Validates if a code structure matches a GLN (Global Location Number). GLN is structurally identical to a GTIN-13 but relies on context.
Examples
iex> GS1.Utils.valid_gln?("4006381333931")
true
@spec wgs84_lat_log_to_ints(float(), float()) :: {:ok, {non_neg_integer(), non_neg_integer()}} | {:error, :invalid_lat_lon}
Converts WGS84 lat/lon coords into integer representation used by GS1.
This function applies the offset and scaling factors defined in the GS1 General Specifications but does not format them into the final data field string.
Parameters
lat_deg: WGS84 latitude in decimal degrees ([-90.0, 90.0]).lon_deg: WGS84 longitude in decimal degrees ([-180.0 and 180.0]).
Returns
{:ok, {x_int, y_int}}- int representations of latitude and longitude.{:error, :invalid_lat_lon}- error if coords is out of range.
Examples
iex> GS1.Utils.wgs84_lat_log_to_ints(-62.0914152, -58.470202900000004)
{:ok, {279085848, 3015297971}}
@spec wgs84_lat_log_to_string_20(float(), float()) :: {:ok, String.t()} | {:error, :invalid_lat_lon}
Converts WGS84 lan, lon coords to 20-char GS1 encoded string.
The resulting string is formatted as a 10-digit encoded latitude followed by a 10-digit encoded longitude.
Each encoded integer is padded with leading zeros to ensure a 10-char length.
This is the reverse operation of string_20_to_wgs84_lat_log/1.
Parameters
lat_deg: WGS84 latitude in decimal degrees ($-90.0$ to $90.0$).lon_deg: WGS84 longitude in decimal degrees ($-180.0$ to $180.0$).
Returns
{:ok, String.t()}- 20-char encoded string.{:error, :invalid_lat_lon}- when input coords are outside the valid WGS84 range.
Examples
iex> GS1.Utils.wgs84_lat_log_to_string_20(-62.0914152, -58.470202900000004)
{:ok, "02790858483015297971"}