Gerando Checksums Luhn

Existem muitas implementações para validar as somas de verificação do Luhn, mas muito poucas para gerá-las. Eu já vieste no entanto, em meus testes, revelou-se buggy e não entendi a lógica por trás da variável delta.

Eu fiz essa função que supostamente deveria gerar checksums do Luhn, mas por alguma razão eu ainda não entendi que as checksums geradas são inválidas metade do tempo.

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

Alguns exemplos:

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

Estou validando as somas de verificação geradascontra esta página, O que eu estou fazendo errado aqui?

Para referência futura, aqui está a função de trabalho.

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

Larguei a variável $ parity pois não precisamos dela para esse propósito e para verificar:

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

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

    return false;
}

questionAnswers(5)

yourAnswerToTheQuestion