有很多驗證Luhn校驗和的實現,但很少用於生成它們。我遇到過this one然而,在我的測試中,它已經顯示出錯誤,並且我不理解delta變量背後的邏輯。生成Luhn校驗和
我做了這個功能,據說應該生成Luhn校驗碼,但由於某種原因,我還沒有理解生成的校驗和是無效的一半時間。
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);
}
一些例子:
Luhn(3); // 37, invalid
Luhn(37); // 372, valid
Luhn(372); // 3728, invalid
Luhn(3728); // 37283, valid
Luhn(37283); // 372837, invalid
Luhn(372837); // 3728375, valid
我驗證生成的校驗against this page,我究竟做錯了什麼?
爲了將來的參考,這裏是工作函數。
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;
}
我放棄了$奇偶性變量,因爲我們並不需要它用於此目的,並覈實:
function Luhn_Verify($number, $iterations = 1)
{
$result = substr($number, 0, - $iterations);
if (Luhn($result, $iterations) == $number)
{
return $result;
}
return false;
}
順便說一下,驗證校驗和與生成校驗和是否相同,並檢查它是否爲零 - 因此所有這些'驗證'例程也可用於生成。 – 2009-09-14 08:05:18
@尼克:是的,但涉及檢查10個不同的數字,我更喜歡反過來(使用生成函數驗證)。 – 2009-09-14 11:59:22
什麼?不,您只需'追加'確認'數字,然後用(9結果)替換最後一位數字。 – 2009-09-14 14:06:53