Luhn Checksummen generieren

Es gibt viele Implementierungen für die Validierung von Luhn-Prüfsummen, aber nur sehr wenige für deren Generierung. Ich bin rübergekommendieses In meinen Tests hat sich jedoch herausgestellt, dass es fehlerhaft ist, und ich verstehe die Logik hinter der Delta-Variablen nicht.

Ich habe diese Funktion gemacht, die angeblich Luhn-Prüfsummen generieren sollte, aber aus irgendeinem Grund, von dem ich noch nicht verstanden habe, dass die generierten Prüfsummen die Hälfte der Zeit ungültig sind.

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

Einige Beispiele:

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

Ich überprüfe die generierten Prüfsummengegen diese Seite, was mache ich hier falsch?

Zum späteren Nachschlagen hier die Arbeitsfunktion.

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

Ich habe die Variable $ parity gelöscht, da wir sie für diesen Zweck nicht benötigen, und um Folgendes zu überprüfen:

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

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

    return false;
}

Antworten auf die Frage(5)

Ihre Antwort auf die Frage