Validate GTIN-8, GTIN-12, GTIN-13 and GTIN-14 (EAN, Barcode) using module of 10.
Reference: https://www.gs1.org/services/how-calculate-check-digit-manually
Validate GTIN-8, GTIN-12, GTIN-13 and GTIN-14 (EAN, Barcode) using module of 10.
Reference: https://www.gs1.org/services/how-calculate-check-digit-manually
<?php | |
class Gtin | |
{ | |
/** | |
* Testa se a string é um GTIN válido nos seguintes termos: | |
* - É uma string | |
* - Contém apenas dígitos numéricos | |
* - Possui 8, 12, 13 ou 14 dígitos | |
* | |
* @param string $gtin | |
* @return bool | |
*/ | |
public static function isValidString(string $gtin) : bool | |
{ | |
return is_string($gtin) and ctype_digit($gtin) and in_array(strlen($gtin), [8, 12, 13, 14]); | |
} | |
/** | |
* Transforma uma string numérica em um array contendo os dígitos que serão calculados | |
* e o dígito verificador. | |
* Ex.: | |
* >>> self::estractCheckDigit('12345678'); | |
* array( | |
* array(1, 2, 3, 4, 5, 6, 7), | |
* 8 | |
* ); | |
* | |
* @param string $gtin | |
* @return array | |
*/ | |
protected static function extractCheckDigit(string $gtin) : array | |
{ | |
// Converte uma string numérica para um array de inteiros | |
$code_digits = array_map('intval', str_split($gtin)); | |
// Separa o último dígito dos restantes | |
$check_digit = array_pop($code_digits); | |
return [$code_digits, $check_digit]; | |
} | |
/** | |
* Calcula o dígito verificador do GTIN recebido | |
* @param array $digits Um array com números inteiros representando todos os dígitos do GTIN exceto o verificador | |
* @return int O dígito verificador, um número entre 0 e 9. | |
*/ | |
protected static function calculateCheckDigit(array $digits) : int | |
{ | |
$sum = 0; | |
$i = count($digits) - 1; | |
/* | |
Intercala multiplicação entre 3 e 1 enquanto soma os resultados. | |
Exemplo: EAN13 => 1234567X | |
1 | 2 | 3 | 4 | 5 | 6 | 7 | X | |
* | * | * | * | * | * | * | | |
3 | 1 | 3 | 1 | 3 | 1 | 3 | | |
= | = | = | = | = | = | = | | |
3 + 2 + 9 + 4 + 15+ 6 + 21| 60 | |
*/ | |
for ($i = 0, $l = count($digits) ; $i < $l ; $i++) { | |
$value = $digits[$l - $i - 1]; // do último ao primeiro | |
$mult = $i & 1 ? 1 : 3; // se for iteração ímpar multiplica por 3 | |
$sum += $value * $mult; // soma o resultdo | |
} | |
// Subtrai o último dígito da soma de 10 | |
$check_digit = 10 - ($sum % 10); | |
// O dígito verificador é o último dígito do resultado | |
return $check_digit % 10; | |
} | |
/** | |
* Calcula o dígito verificador do GTIN e retorna true se for válido. | |
* @param string $gtin | |
* @return boolean | |
*/ | |
public static function validate(string $gtin) : bool | |
{ | |
if (! self::isValidString($gtin)) { | |
return false; | |
} | |
list($digits, $check_digit) = self::extractCheckDigit($gtin); | |
$correct_check = self::calculateCheckDigit($digits); | |
return $correct_check === $check_digit; | |
} | |
} |