-
Notifications
You must be signed in to change notification settings - Fork 406
/
TypeCode32.php
114 lines (100 loc) · 2.94 KB
/
TypeCode32.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
namespace Picqer\Barcode\Types;
use Picqer\Barcode\Barcode;
use Picqer\Barcode\Exceptions\InvalidCharacterException;
use Picqer\Barcode\Exceptions\InvalidCheckDigitException;
use Picqer\Barcode\Exceptions\InvalidLengthException;
/*
* CODE 32 - italian pharmaceutical
* General-purpose code in very wide use world-wide
*/
class TypeCode32 extends TypeCode39
{
protected array $conversionTable32 = [
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'10' => 'B',
'11' => 'C',
'12' => 'D',
'13' => 'F',
'14' => 'G',
'15' => 'H',
'16' => 'J',
'17' => 'K',
'18' => 'L',
'19' => 'M',
'20' => 'N',
'21' => 'P',
'22' => 'Q',
'23' => 'R',
'24' => 'S',
'25' => 'T',
'26' => 'U',
'27' => 'V',
'28' => 'W',
'29' => 'X',
'30' => 'Y',
'31' => 'Z'
];
public function getBarcode(string $code): Barcode
{
// Validate code 32.
$stringLength = strlen($code);
for ($i = 0; $i < $stringLength; ++$i) {
if (!is_numeric($code[$i])) {
throw new InvalidCharacterException('Character "' . $code[$i] . '" is not supported.');
}
}
// Prepare code 32.
$code = str_pad($code, 8, '0', STR_PAD_LEFT);
$checksumDigit = $this->checksum_code32(substr($code, 0, 8));
$stringLength = max($stringLength, 8);
if ($stringLength === 8) {
$code .= $checksumDigit;
++$stringLength;
}
if ($stringLength !== 9) {
throw new InvalidLengthException('Only a code consisting of no more than 9 numbers is supported.');
}
if ($code[8] !== $checksumDigit) {
throw new InvalidCheckDigitException('Provided checksum digit is wrong for provided code.');
}
// Convert code 32 into code 39.
$code39 = '';
$codeElab = $code;
for ($e = 5; $e >= 0; --$e) {
$code39 .= $this->conversionTable32[intval($codeElab / pow(32, $e))];
$codeElab = $codeElab % pow(32, $e);
}
// Return barcode data for code 39.
return parent::getBarcode($code39);
}
/**
* Calculate CODE 32 checksum (modulo 10).
*
* @param string $code code to represent.
* @return string char checksum.
* @protected
*/
protected function checksum_code32(string $code): string
{
$checksum = 0;
foreach (str_split($code) as $i => $c) {
if (0 === $i % 2) {
$checksum += (int)$c;
} else {
$c = 2 * (int)$c;
$checksum += (int)floor($c / 10) + ($c % 10);
}
}
return (string)($checksum % 10);
}
}