Capitulo 4: GS1 Application Identifiers
Que es un Application Identifier
Un Application Identifier (AI) es un prefijo de 2 a 4 digitos que precede a un campo de datos y define:
- Que tipo de dato es (GTIN, lote, fecha, peso, etc.)
- Cuantos caracteres tiene el dato (longitud fija o variable)
- Que formato usa (numerico, alfanumerico, fecha)
Sin AIs, un escaner leeria una cadena de caracteres sin saber que significa cada parte. Los AIs son el “diccionario” que permite interpretar la informacion.
Tabla de AIs principales
| AI | Nombre | Formato | Long. | Fija/Var | Ejemplo |
|---|---|---|---|---|---|
| (00) | SSCC | n18 | 18 | Fija | (00)306141410000000012 |
| (01) | GTIN | n14 | 14 | Fija | (01)09521234543213 |
| (02) | GTIN de items contenidos | n14 | 14 | Fija | (02)09521234543213 |
| (10) | Numero de lote | an..20 | 1-20 | Variable | (10)LOTE-AB1 |
| (11) | Fecha de produccion | n6 (YYMMDD) | 6 | Fija | (11)260101 |
| (17) | Fecha de vencimiento | n6 (YYMMDD) | 6 | Fija | (17)261231 |
| (21) | Numero de serie | an..20 | 1-20 | Variable | (21)SN001 |
| (30) | Cantidad | n..8 | 1-8 | Variable | (30)48 |
| (310n) | Peso neto en kg | n6 | 6 | Fija | (3102)001500 |
| (410) | GLN destino (Ship To) | n13 | 13 | Fija | (410)0614141073467 |
| (414) | GLN de ubicacion fisica | n13 | 13 | Fija | (414)0614141073467 |
| (420) | Codigo postal destino | an..20 | 1-20 | Variable | (420)28001 |
Notas sobre el formato
- n: numerico
- an: alfanumerico
- ..20: hasta 20 caracteres (longitud variable)
- (310n): la
nindica el numero de decimales.(3102)001500significa 0015.00 kg = 15.00 kg - Las fechas usan formato YYMMDD. Si el dia es
00, significa “ultimo dia del mes”
Que es un Element String
Un Element String es la concatenacion de uno o mas pares AI+dato. Es lo que realmente se codifica dentro de un codigo de barras GS1-128 o DataMatrix.
Ejemplo completo
(01)09521234543213(17)261231(10)LOTE-AB1(21)SN001
Desglose:
| AI | Dato | Significado |
|---|---|---|
| (01) | 09521234543213 | GTIN del producto |
| (17) | 261231 | Vence el 31 de diciembre de 2026 |
| (10) | LOTE-AB1 | Lote de produccion |
| (21) | SN001 | Numero de serie unico |
Este Element String identifica una unidad especifica de un producto: sabemos que es, cuando vence, de que lote viene y cual es su numero de serie individual.
Separadores: el problema de los AIs de longitud variable
Los AIs de longitud fija (como 01, 00, 17) no necesitan separador porque el parser sabe exactamente cuantos caracteres leer. Pero los AIs de longitud variable (como 10, 21, 420) necesitan indicar donde terminan.
FNC1 en GS1-128
En codigos de barras GS1-128, se usa un caracter especial llamado FNC1 (Function Code 1) como separador. No es un caracter visible: es una instruccion para el escaner.
GS (Group Separator) en transmision de datos
Cuando los datos se transmiten como texto (desde un escaner via USB/serial), el FNC1 se reemplaza por el caracter ASCII GS (Group Separator, \x1D, codigo 29).
Regla clave
El separador FNC1/GS se coloca al final de un AI de longitud variable, excepto si es el ultimo AI del Element String.
Ejemplo con separadores (usando {GS} para representar el caracter):
(01)09521234543213(10)LOTE-AB1{GS}(21)SN001{GS}(17)261231
En la practica, para evitar separadores innecesarios, se colocan los AIs de longitud fija al final:
(01)09521234543213(10)LOTE-AB1{GS}(21)SN001(17)261231
Aqui (17) tiene longitud fija, asi que al estar al final no necesita separador, y (21) al no ser el ultimo AI variable, si lo necesitaria… pero si lo ponemos justo antes de un AI fijo, solo necesitamos un GS despues de (10).
Parsear un Element String
// Definicion de AIs conocidos con su longitud
const AI_DEFS: Record<string, { length?: number; label: string }> = {
'00': { length: 18, label: 'SSCC' },
'01': { length: 14, label: 'GTIN' },
'02': { length: 14, label: 'GTIN contenido' },
'10': { label: 'Lote' },
'11': { length: 6, label: 'Fecha produccion' },
'17': { length: 6, label: 'Fecha vencimiento' },
'21': { label: 'Serie' },
'30': { label: 'Cantidad' },
'410': { length: 13, label: 'GLN destino' },
'414': { length: 13, label: 'GLN ubicacion' },
'420': { label: 'CP destino' },
};
interface ParsedAI {
ai: string;
label: string;
value: string;
}
function parseElementString(raw: string): ParsedAI[] {
const GS = '\x1D';
const results: ParsedAI[] = [];
let pos = 0;
// Limpiar parentesis si existen (formato HRI)
const clean = raw.replace(/[()]/g, '');
while (pos < clean.length) {
if (clean[pos] === GS) { pos++; continue; }
// Intentar AIs de 3, luego 2 digitos
const candidates = [3, 2];
let matched = false;
for (const len of candidates) {
const aiCandidate = clean.substring(pos, pos + len);
const def = AI_DEFS[aiCandidate];
if (def) {
pos += len;
let value: string;
if (def.length) {
value = clean.substring(pos, pos + def.length);
pos += def.length;
} else {
const gsIndex = clean.indexOf(GS, pos);
const end = gsIndex === -1 ? clean.length : gsIndex;
value = clean.substring(pos, end);
pos = end;
}
results.push({ ai: aiCandidate, label: def.label, value });
matched = true;
break;
}
}
if (!matched) {
throw new Error(`AI desconocido en posicion ${pos}: ${clean.substring(pos, pos + 4)}`);
}
}
return results;
}
// Ejemplo
const parsed = parseElementString('(01)09521234543213(17)261231(10)LOTE-AB1(21)SN001');
console.log(parsed);
// [
// { ai: '01', label: 'GTIN', value: '09521234543213' },
// { ai: '17', label: 'Fecha vencimiento', value: '261231' },
// { ai: '10', label: 'Lote', value: 'LOTE-AB1' },
// { ai: '21', label: 'Serie', value: 'SN001' }
// ]
Ahora que entendemos como se estructuran los datos dentro de los codigos, en el proximo capitulo veremos el GS1-128: el codigo de barras logistico que empaqueta todo esto en un simbolo escaneable.