60f76d5919
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
1.3 KiB
PHP
55 lines
1.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support;
|
|
|
|
final class InnValidator
|
|
{
|
|
public static function isValid(string $inn, string $subjectType): bool
|
|
{
|
|
if ($subjectType === 'individual') {
|
|
return true; // физлицу ИНН не требуется (SP2)
|
|
}
|
|
if (! ctype_digit($inn)) {
|
|
return false;
|
|
}
|
|
|
|
return match ($subjectType) {
|
|
'legal_entity' => self::valid10($inn),
|
|
'sole_proprietor' => self::valid12($inn),
|
|
default => false,
|
|
};
|
|
}
|
|
|
|
private static function valid10(string $inn): bool
|
|
{
|
|
if (strlen($inn) !== 10) {
|
|
return false;
|
|
}
|
|
|
|
return self::checksum($inn, [2, 4, 10, 3, 5, 9, 4, 6, 8]) === (int) $inn[9];
|
|
}
|
|
|
|
private static function valid12(string $inn): bool
|
|
{
|
|
if (strlen($inn) !== 12) {
|
|
return false;
|
|
}
|
|
|
|
return self::checksum($inn, [7, 2, 4, 10, 3, 5, 9, 4, 6, 8]) === (int) $inn[10]
|
|
&& self::checksum($inn, [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8]) === (int) $inn[11];
|
|
}
|
|
|
|
/** @param int[] $weights */
|
|
private static function checksum(string $inn, array $weights): int
|
|
{
|
|
$sum = 0;
|
|
foreach ($weights as $i => $w) {
|
|
$sum += $w * (int) $inn[$i];
|
|
}
|
|
|
|
return ($sum % 11) % 10;
|
|
}
|
|
}
|