Validation d'un numéro SIRET avec l'algorithme de Luhn

Publié le 24/09/2020 • Actualisé le 24/09/2020


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

Dans ce bout de code, nous allons voir comment vérifier si un numéro SIRET est valide avec l'algorithme de Luhn. Veuillez consulter la page Wikipédia pour plus d'explications. Ici, vous avez le code qui retourne si le numéro est valide ou pas. Maintenant vous pouvez injecter ce service dans un validateur personnalisé afin de faire les choses correctement. Veuillez noter que même si un numéro est considéré comme valide, ça n'assure pas qu'il y ait réellement une entreprise qui lui est associé.


<?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 ≫  Plus sur Stackoverflow   Lire la doc  Plus sur le web  Snippet aléatoire

  Travaillez avec moi !

<?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);
    }
}