Skip to content

Commit 07d8a60

Browse files
authored
Merge pull request #165 from Bernhard-Krop/code-32
Fixing problems with barcode type code 32
2 parents b98f110 + fbc6395 commit 07d8a60

File tree

1 file changed

+62
-8
lines changed

1 file changed

+62
-8
lines changed

src/Types/TypeCode32.php

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace Picqer\Barcode\Types;
44

55
use Picqer\Barcode\Barcode;
6+
use Picqer\Barcode\Exceptions\InvalidCharacterException;
7+
use Picqer\Barcode\Exceptions\InvalidCheckDigitException;
8+
use Picqer\Barcode\Exceptions\InvalidLengthException;
69

710
/*
811
* CODE 32 - italian pharmaceutical
@@ -47,14 +50,65 @@ class TypeCode32 extends TypeCode39
4750

4851
public function getBarcodeData(string $code): Barcode
4952
{
50-
$code39 = '';
53+
// Validate code 32.
54+
$stringLength = strlen($code);
55+
56+
for ($i = 0; $i < $stringLength; ++$i) {
57+
if (!is_numeric($code[$i])) {
58+
throw new InvalidCharacterException('Character "' . $code[$i] . '" is not supported.');
59+
}
60+
}
61+
62+
// Prepare code 32.
63+
$code = str_pad($code, 8, '0', STR_PAD_LEFT);
64+
$checksumDigit = $this->checksum_code32(substr($code, 0, 8));
65+
$stringLength = max($stringLength, 8);
66+
67+
if ($stringLength === 8) {
68+
$code .= $checksumDigit;
69+
++$stringLength;
70+
}
71+
if ($stringLength !== 9) {
72+
throw new InvalidLengthException('Only a code consisting of no more than 9 numbers is supported.');
73+
}
74+
if ($code[8] !== $checksumDigit) {
75+
throw new InvalidCheckDigitException('Provided checksum digit is wrong for provided code.');
76+
}
77+
78+
// Convert code 32 into code 39.
79+
$code39 = '';
5180
$codeElab = $code;
52-
53-
for ($e = 5; $e >= 0; $e--) {
54-
$code39 .= $this->conversionTable32[intval($codeElab / pow(32,$e))];
55-
$codeElab = intval($codeElab % pow(32,$e));
56-
}
57-
81+
82+
for ($e = 5; $e >= 0; --$e) {
83+
$code39 .= $this->conversionTable32[intval($codeElab / pow(32, $e))];
84+
$codeElab = $codeElab % pow(32, $e);
85+
}
86+
87+
// Return barcode data for code 39.
5888
return parent::getBarcodeData($code39);
59-
}
89+
}
90+
91+
92+
/**
93+
* Calculate CODE 32 checksum (modulo 10).
94+
*
95+
* @param string $code code to represent.
96+
* @return string char checksum.
97+
* @protected
98+
*/
99+
protected function checksum_code32(string $code): string
100+
{
101+
$s = 0;
102+
103+
foreach (str_split($code) as $i => $c) {
104+
if (0 === $i % 2) {
105+
$s += (int)$c;
106+
} else {
107+
$c = 2 * (int)$c;
108+
$s += (int)floor($c / 10) + ($c % 10);
109+
}
110+
}
111+
112+
return (string)$s % 10;
113+
}
60114
}

0 commit comments

Comments
 (0)