Génération de chèques Luhn

Il y a beaucoup de mises en œuvre pour la validation de Luhn sommes mais très peu pour les générer. Je suis venu à travers cette une cependant, dans mes tests, il a révélé être buggy et je ne comprends pas la logique derrière le delta variable.

J'ai fait cette fonction qui est censé devrait généré Luhn sommes, mais pour une raison que je n'ai pas encore compris l'généré des sommes de contrôle invalide la moitié du temps.

function Luhn($number, $iterations = 1)
{
    while ($iterations-- >= 1)
    {
        $stack = 0;
        $parity = strlen($number) % 2;
        $number = str_split($number, 1);

        foreach ($number as $key => $value)
        {
            if ($key % 2 == $parity)
            {
                $value *= 2;

                if ($value > 9)
                {
                    $value -= 9;
                }
            }

            $stack += $value;
        }

        $stack = 10 - $stack % 10;

        if ($stack == 10)
        {
            $stack = 0;
        }

        $number[] = $stack;
    }

    return implode('', $number);
}

Quelques exemples:

Luhn(3); //37, invalid
Luhn(37); //372, valid
Luhn(372); //3728, invalid
Luhn(3728); //37283, valid
Luhn(37283); //372837, invalid
Luhn(372837); //3728375, valid

Je suis la validation de l'généré sommes à l'encontre de cette pagece que je fais mal?


Référence pour l'avenir, ici, c'est le travail de la fonction.

function Luhn($number, $iterations = 1)
{
    while ($iterations-- >= 1)
    {
        $stack = 0;
        $number = str_split(strrev($number), 1);

        foreach ($number as $key => $value)
        {
            if ($key % 2 == 0)
            {
                $value = array_sum(str_split($value * 2, 1));
            }

            $stack += $value;
        }

        $stack %= 10;

        if ($stack != 0)
        {
            $stack -= 10;
        }

        $number = implode('', array_reverse($number)) . abs($stack);
    }

    return $number;
}

J'ai laissé tomber l' $parité variable puisque nous n'avons pas besoin à cette fin, et pour vérifier:

function Luhn_Verify($number, $iterations = 1)
{
    $result = substr($number, 0, - $iterations);

    if (Luhn($result, $iterations) == $number)
    {
        return $result;
    }

    return false;
}

source d'informationauteur Alix Axel