Validating a French SIRET number with the Luhn algorithm
Published on 2020-09-24 • Modified on 2020-09-24
In this snippet, we will see how to check if a French SIRET number is valid with the Luhn algorithm. Check out the Wikipedia page for more explanations. Here you have the main code that returns is the number is valid or not. Now, you can inject this service in a custom validator to make things clean. Note that even a number a considered valid, it doesn't mean that's there is an actual company associated to it.
<?php
declare(strict_types=1);
namespace App\Tools;
class Siret
{
public const SIRET_LENGTH = 14;
/**
* Be careful, it doesn't handle exceptions like "MONACOCONFO001".
*
* @see https://en.wikipedia.org/wiki/SIRET_code
*/
public function isValid(?string $siret): bool
{
$siret = trim((string) $siret);
if (!is_numeric($siret) || \strlen($siret) !== self::SIRET_LENGTH) {
return false;
}
$sum = 0;
for ($i = 0; $i < self::SIRET_LENGTH; ++$i) {
if ($i % 2 === 0) {
$tmp = ((int) $siret[$i]) * 2;
$tmp = $tmp > 9 ? $tmp - 9 : $tmp;
} else {
$tmp = $siret[$i];
}
$sum += $tmp;
}
return !($sum % 10 !== 0);
}
}
≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫ More on Stackoverflow Read the doc More on the web Random snippet
<?php
declare(strict_types=1);
namespace App\Tests\Integration\Controller\Snippets;
use App\Tools\Siret;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
* @see Siret
*/
final class Snippet114Test extends KernelTestCase
{
private Siret $siret;
protected function setUp(): void
{
$this->siret = self::getContainer()->get(Siret::class);
}
/**
* @return iterable<int, array{0: string, 1: bool}>
*/
public function siretProvider(): iterable
{
// NOK
yield ['', false];
yield ['1234567890123', false];
yield ['1234567890123A', false];
yield ['MONACOCONFO001', false];
yield ['21218711783329', false]; // generated with random_int
yield ['92958655678109', false]; // generated with random_int
// OK
yield ['80365813700036', true];
}
/**
* @dataProvider siretProvider
*
* @see Siret::isValid
*/
public function testIsValid(string $siret, bool $isValid): void
{
self::assertSame($this->siret->isValid($siret), $isValid);
}
}