【发布时间】:2009-09-13 22:04:06
【问题描述】:
验证 Luhn 校验和的实现有很多,但生成它们的实现却很少。我遇到过this one,但是在我的测试中发现它有问题,我不明白 delta 变量背后的逻辑。
我已经创建了这个函数,据说应该生成 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;
}
我删除了 $parity 变量,因为我们不需要它来验证:
function Luhn_Verify($number, $iterations = 1)
{
$result = substr($number, 0, - $iterations);
if (Luhn($result, $iterations) == $number)
{
return $result;
}
return false;
}
【问题讨论】:
-
顺便说一句,验证校验和与生成它并检查它是否为零是相同的 - 所以所有这些“验证”例程也可以用来生成。
-
@Nick:是的,但这涉及检查 10 个不同的数字,我更喜欢相反的方式(使用 generate 函数验证)。
-
什么?不,您只需“验证”附加 0 的数字,然后将最后一位数字替换为 (9-result)。
-
对不起,你说得对,我误解了你的说法。
-
到目前为止,我只发现您在 PHP 中的 Luhn 生成代码实现是可用的。我认为如果你用它在 github 中创建一个简单的存储库会很有趣。你怎么看?
标签: php algorithm checksum check-digit luhn