-
Notifications
You must be signed in to change notification settings - Fork 5
/
LuxembourgIdValidator.php
84 lines (69 loc) · 2.07 KB
/
LuxembourgIdValidator.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
<?php
namespace Reducktion\Socrates\Core\Luxembourg;
use Reducktion\Socrates\Contracts\IdValidator;
use Reducktion\Socrates\Exceptions\InvalidLengthException;
class LuxembourgIdValidator implements IdValidator
{
public function validate(string $id): bool
{
$idLength = strlen($id);
if ($idLength !== 13) {
throw new InvalidLengthException(
'Luxembourger national identification',
'11',
$idLength
);
}
$ninArray = array_map(
static function ($digit) {
return (int) $digit;
},
str_split($id)
);
return $this->checkLuhn($ninArray) && $this->checkVerhoeff($ninArray);
}
private function checkLuhn(array $id): bool
{
array_pop($id);
$parity = count($id) % 2;
$sum = 0;
foreach ($id as $key => $value) {
if ($key % 2 === $parity) {
$value *= 2;
}
$sum += ($value >= 10 ? $value - 9 : $value);
}
return $sum % 10 === 0;
}
private function checkVerhoeff(array $id): bool
{
$multipliers = [
[0,1,2,3,4,5,6,7,8,9],
[1,2,3,4,0,6,7,8,9,5],
[2,3,4,0,1,7,8,9,5,6],
[3,4,0,1,2,8,9,5,6,7],
[4,0,1,2,3,9,5,6,7,8],
[5,9,8,7,6,0,4,3,2,1],
[6,5,9,8,7,1,0,4,3,2],
[7,6,5,9,8,2,1,0,4,3],
[8,7,6,5,9,3,2,1,0,4],
[9,8,7,6,5,4,3,2,1,0],
];
$permutations = [
[0,1,2,3,4,5,6,7,8,9],
[1,5,7,6,2,8,3,0,9,4],
[5,8,0,3,7,9,6,1,4,2],
[8,9,1,6,0,4,3,5,2,7],
[9,4,5,3,1,2,6,8,7,0],
[4,2,8,6,5,7,3,9,0,1],
[2,7,9,3,8,0,6,4,1,5],
[7,0,4,6,9,1,3,2,5,8],
];
$id = array_reverse($id);
$checksum = 0;
foreach ($id as $i => $iValue) {
$checksum = $multipliers[$checksum][$permutations[($i % 8)][$iValue]];
}
return $checksum === 0;
}
}