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; | |
| } | |
| } |