Generowanie sum kontrolnych Luhn

Istnieje wiele implementacji do sprawdzania sum kontrolnych Luhna, ale bardzo niewiele do ich generowania. Natknąłem sięten jednak w moich testach okazało się, że jest buggy i nie rozumiem logiki kryjącej się za zmienną delta.

Zrobiłem tę funkcję, która podobno powinna wygenerować sumy kontrolne Luhna, ale z jakiegoś powodu nie zrozumiałem jeszcze, że wygenerowane sumy kontrolne są niepoprawne w połowie.

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

Kilka przykładów:

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

Sprawdzam poprawność wygenerowanych sum kontrolnychna tej stronie, co tu robię źle?

Dla przyszłego odniesienia, tutaj jest funkcja robocza.

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

Usunąłem zmienną $ parzystości, ponieważ nie potrzebujemy jej do tego celu, i zweryfikować:

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

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

    return false;
}

questionAnswers(5)

yourAnswerToTheQuestion