European Article Number

Código de barras EAN-13. El primer dígito siempre se sitúa fuera del código. Además, el signo antilambda (>) se utiliza para indicar «zonas en blanco», necesarias para que los escáneres de códigos de barras funcionen correctamente.

El número de artículo europeo (en inglés European Article Number o EAN) es un sistema de códigos de barras adoptado por más de cien países y cerca de un millón de empresas. En el año 2005, la asociación EAN se fusionó con la UCC para formar una nueva y única organización mundial identificada como GS1, con sede en Bélgica.

Estructura y partes

El código EAN más usual es EAN-13, constituido por trece (13) dígitos y con una estructura dividida en cuatro partes:

Por ejemplo, para 123456789041 el dígito de control será:

El código quedará así: 1234567890418.

Algoritmo informático

Perl

# Cálculo del dígito de control EAN
my $ean      = '750863367001';             # Valor de prueba
my $checksum = 1000;           
my $i        = 0;

for my $digit (split //, reverse $ean) {   # Recorremos el $ean de forma inversa, dígito por dígito
    $checksum                              # Modificamos $checksum
       -= $i++ % 2                         # según la posición del dígito:
        ? $digit                           # posición impar
        : $digit*3                         # posición par
        ;
}

$checksum %= 10;                           # Ajustamos a la decena inmediatamente inferior

print "Dígito de control: $checksum\n";
print "Código EAN: $ean$checksum\n";

PHP

// Cálculo del dígito de control EAN
function ean13_checksum ($message) {
  $checksum = 0;
  foreach (str_split(strrev($message)) as $pos => $val) {
    $checksum += $val * (3 - 2 * ($pos % 2));
  }
  return ((10 - ($checksum % 10)) % 10);
}

// Valor de prueba (sin dígito de control)
$ean = '931804231236';
echo 'Digito de control: ', ean13_checksum($ean);

C#

// Cálculo del dígito de control EAN
string ean = "123456789012";
int sum = 0;
int sumOdd = 0;
var digit = 0;

for (int i = ean.Length; i >= 1; i--)
{
    digit = Convert.ToInt32(ean.Substring(i - 1, 1));
    if (i % 2 != 0)
    {
       sumOdd += digit;
    }
    else
    {
       sum += digit;
    }
}

digit = (sumOdd) + (sum * 3);

int checkSum = (10 - (digit % 10)) % 10;
Console.Write("Dígito de control: " + checkSum.ToString());

Python 3

EAN = "123456789041"

def ean_checksum(code: str) -> int:
    digits = [int(i) for i in reversed(code)]
    return (10 - (3 * sum(digits[0::2]) + (sum(digits[1::2])))) % 10

print(f"Dígito de control: {ean_checksum(EAN)}")

Python 2

EAN = "123456789041"

def eanCheck(ean):
    checksum = 0
    for i, digit in enumerate(reversed(ean)):
        checksum += int(digit) * 3 if (i % 2 == 0) else int(digit)
    
    return (10 - (checksum % 10)) % 10

print "Digito de control: %d" %eanCheck(EAN)

Visual Basic 6.0

'Verifica que sea un código EAN válido

Function EanValido(ByVal Ean As String) As Boolean
    Dim Sum As Integer, Digit As Integer, i As Integer
    
    Sum = 0
    For i = 1 To Len(Ean) - 1
        Digit = Mid(Ean, i, 1)
        Sum = Sum + Digit * IIf(i Mod 2 = 0, 3, 1)
    Next
 
    EanValido = Right(Ean, 1) = ((10 - Sum Mod 10) Mod 10)
End Function

JavaScript

// Cálculo del dígito de control EAN
function ean13_checksum(message) {
    var checksum = 0;
    message = message.split('').reverse();
    for(var pos in message){
        checksum += message[pos] * (3 - 2 * (pos % 2));
    }
    return ((10 - (checksum % 10 )) % 10);
}
// Valor de prueba (sin dígito de control)
var ean = '123456789041';
console.log(ean13_checksum(ean));

Bash compatible

ean13_checksum ()
{
	local EAN="$1"
	local Test=''
	local CurDigit=''
	local CurReversePos=''
	local CurPos=''
	local OddSum=''
	local EvenSum=''
	local TotalSum=''
	local UpperTenth=''
	local Value=0
	
	Test="$(printf '%s' "$EAN" | sed -e 's|[^0123456789]||g')"
	if [ "$EAN" != "" ] && [ "$Test" = "$EAN" ] ; then
		CurDigitNr=${#EAN}
		CurReversePos=1
		while [ $CurDigitNr -gt 0 ] ; do
			CurDigit="$(printf '%s' "$EAN" | cut -c ${CurDigitNr}-${CurDigitNr})"
			if [ $((CurReversePos % 2)) -ne 0 ] ; then
				OddSum=$((OddSum + CurDigit))
			else
				EvenSum=$((EvenSum + CurDigit))
			fi
			CurReversePos=$((CurReversePos + 1))
			CurDigitNr=$((CurDigitNr - 1))
		done
		OddSum=$((OddSum * 3))
		TotalSum=$((OddSum + EvenSum))
		if [ ${#TotalSum} -eq 1 ] ; then
			UpperTenth=10
		else
			UpperTenth="$(printf '%s' "$TotalSum" | sed -e 's|.$||')"
			UpperTenth="$((UpperTenth + 1))0"
		fi
		Value=$((UpperTenth - TotalSum))
		CurPos=${#Value}
		echo "$Value" | cut -c ${CurPos}-${CurPos}
	fi
}

ean13_checksum 123456789041

ABAP

    CALL FUNCTION 'MARA_EAN11'
         EXPORTING
              P_MATNR      = MARA-MATNR
              P_NUMTP      = MARA-NUMTP
              P_EAN11      = MARA-EAN11
              P_MEINH      = MARA-MEINS
              RET_EAN11    = LMARA-EAN11
              RET_NUMTP    = LMARA-NUMTP
              BINPT_IN     = SY-BINPT
              P_MESSAGE    = ' '
              ERROR_FLAG   = EAN_FEHLERFLG
              P_HERKUNFT   = 'A'         " Für Abmessungen / EAN
              GDS_RELEVANT = MARA-GDS_RELEVANT
         IMPORTING
            P_NUMTP      = MARA-NUMTP
            P_EAN11      = MARA-EAN11
            VB_FLAG_MEAN = RMMG2-VB_MEAN
            MSGID        = MSGID       " s. weiter unten
            MSGTY        = MSGTY
            MSGNO        = MSGNO
            MSGV1        = MSGV1
            MSGV2        = MSGV2
            MSGV3        = MSGV3
            MSGV4        = MSGV4
       TABLES
            MARM_EAN     = MARM_EAN
            MEAN_ME_TAB  = MEAN_ME_TAB " NEU: AHE 24.10.95
          ME_TAB       = ME_TAB
          YDMEAN       = YDMEAN
     EXCEPTIONS
          EAN_ERROR    = 1
          OTHERS       = 2....

Delphi

// Cálculo del dígito de control EAN
function cc_CalcDV_Ean(Ean: String): Integer; 
{ Calcula y devuelve el dígito verificador de una cadena de código EAN13 o EAN8
  Devcuelve -1 en caso de ser incorrecto. }
var
  SP, SI, I, L:Integer;
  Impar: Boolean;
begin
  L:= Length(Ean);
  if (L=8) or (L=13) then
    begin
    SI:= 0;
    SP:= 0;
    I:= L-1;
    Impar:= Odd(L);
    repeat                                     // Bucle para sumar los valores discriminando posiciones pares e impares
      if Impar then SI:= SI + StrToInt(Ean[I]) else SP:= SP + StrToInt(Ean[I]);
      Impar:= not Impar;
      I:= I - 1;
    until I =0;
    if Impar then SI:= SI*3 else SP:= SP*3;    // Multiplica por tres según la longitud del código
    Result:= 10-(SI+SP) mod 10;                // Calcula el dígito de verificación
  end else Result:= -1;
end;

Java

/**
 * Cálculo del código de control
 */
private int controlCodeCalculator(String firstTwelveDigits)
{
     char[] charDigits = firstTwelveDigits.toCharArray();
     int[] ean13 =
     {
        1, 3
     };
     int sum = 0;
     for(int i = 0; i < charDigits.length; i++)
     {
         sum += Character.getNumericValue(charDigits[i]) * ean13[i % 2];
     }
     int checksum = 10 - sum % 10;

     if(checksum == 10)
         checksum = 0;

     return checksum;
}

SQL

DECLARE @initialBarcode VARCHAR(13), @auxBarcode VARCHAR(13), @finalBarcode VARCHAR(13)

SET @auxBarcode =  REVERSE(@initialBarcode)

DECLARE @verifierCode INT = 0
SELECT 
	@verifierCode = CASE 
		WHEN i % 2 = 0 THEN 
			@verifierCode + SUBSTRING(@auxBarcode, i, 1) 
		ELSE
			@verifierCode + (SUBSTRING(@auxBarcode, i, 1) * 3)
	END
FROM  dbo.NumbersTable(1,12,1) --- FALTA ESTO EN EL SQL

SET @verifierCode = RIGHT((10 - RIGHT(@verifierCode,1)),1)

SET @finalBarcode = CONCAT(@initialBarcode, @verifierCode)

RETURN @finalBarcode

MATLAB

if isnumeric(ean)
    ean = sprintf('%013d', ean);
end;
checksum = sum((ean(1:end-1)-'0').*(rem([0:11],2)*2+1));
if rem(10 - (rem(checksum,10)), 10) ~= ean(13)-'0'
    disp('El checksum no parece ser correcto')
end;

Visual FoxPro

FUNCTION DIGITO_VERIFICADOR_EAN
LPARAMETERS tcCodigoBarras
LOCAL lnSuma, lnI, lnDigito, lnDigitoVerificador
   
  lnSuma = 0
   
  FOR lnI = Len(tcCodigoBarras) TO 1 STEP -1
    lnDigito = Val(Substr(tcCodigoBarras, lnI, 1))
    IF (Mod(Len(tcCodigoBarras) - lnI + 1, 2)) <> 0 THEN
      lnSuma = lnSuma + lnDigito * 3
    ELSE
      lnSuma = lnSuma + lnDigito
    ENDIF
  ENDFOR
   
  lnDigitoVerificador = Mod(10 - Mod(lnSuma, 10), 10)
   
  RETURN (lnDigitoVerificador)
ENDFUNC

Excel

El ejemplo calcula un EAN13 para la celda A1, si fuera 123456789041 añadiría un 8 como dígito de control

=SI(LARGO(A1)>12;"MAS de 13";SI(ESERROR(A1*1);"NO NUMERICO";CONCATENAR(REPETIR(0;12-LARGO(A1));A1)&RESIDUO((10-(DERECHA(((SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);2;1));"0")+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);4;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);6;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);8;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);10;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);12;1));"0")))*3)+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);1;1));"0")+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);3;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);5;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);7;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);9;1));"0"))+(SI.ERROR(VALOR(EXTRAEB(TEXTO(A1;0);11;1));"0")));1)));10)))

LibreOffice Calc & Google Sheets

El ejemplo calcula un EAN13 para la celda A6, si fuera 123456789041 añadiría un 8 como dígito de control

=IF(ISNUMBER(VALUE(A6));
    IF(LEN(A6)=12
       ;A6&IF(MOD(
              (MID(A6;2;1)+MID(A6;4;1)+MID(A6;6;1)+
              MID(A6;8;1)+MID(A6;10;1)+MID(A6;12;1))*3+
              LEFT(A6;1)+MID(A6;3;1)+MID(A6;5;1)+
              MID(A6;7;1)+MID(A6;9;1)+MID(A6;11;1)
                       ;10)=0;0;10-MOD(
              (MID(A6;2;1)+MID(A6;4;1)+MID(A6;6;1)+
              MID(A6;8;1)+MID(A6;10;1)+MID(A6;12;1))*3+
              LEFT(A6;1)+MID(A6;3;1)+MID(A6;5;1)+
              MID(A6;7;1)+MID(A6;9;1)+MID(A6;11;1)
                       ;10)
           )
       ;"Deben ser 12 dígitos")
    ;"Deben ser dígitos")

C

// Se presupone que la variable ean contiene un código EAN válido

char ean[13] = "123456789041";
char *car = ean + 12;
int par = !0;
int control = 0;
int num;

while(car-- - ean) {
    num = *car - '0';
    if(par) num *= 3;
    par = !par;
    control += num;
}

return 10 - control % 10;

Ruby

# controlar que el código EAN sea válido

def ean_valid?(code)
    digits = code.chars.map(&:to_i);
    sum = 0.upto(digits.size-1).sum{|i| digits[i] * (i.odd? ? 3 : 1)}
    digits.last == (10 - sum) % 10 
end

Dart

// controlar que el código EAN sea válido

bool  eanValid(String code) {
    final digits = code.split('').map((x) => int.parse(x)).toList();

    var sum = 0;
    for (var i = 0; i < digits.length - 1; i++) {
      sum += digits[i] * (i.isOdd ? 3 : 1);
    }

    return digits.last == (10 - sum) % 10;
  }

Véase también

Referencias

  1. ↑ «BOE.es - Documento DOUE-L-2015-82354». www.boe.es. Consultado el 31 de marzo de 2020.
  2. ↑ Flamarique, Sergi (31 de marzo de 2019). Manual de gestión de almacenes. MARGE BOOKS. ISBN 978-84-17313-84-5. Consultado el 31 de marzo de 2020.
  3. ↑ «Información sobre los identificadores únicos de producto - Ayuda de Manufacturer Center». support.google.com. Consultado el 31 de marzo de 2020.
  4. ↑ Datos del año 2003.
  5. ↑ Diez pasos para implantar el Código de Barras

Enlaces externos