如何使用 Luhn 算法创建信用卡验证器?

Posted

技术标签:

【中文标题】如何使用 Luhn 算法创建信用卡验证器?【英文标题】:How can I create a credit card validator using Luhn's algorithm? 【发布时间】:2021-10-29 19:29:11 【问题描述】:

我正在尝试使用 Luhn 算法创建一个简单的信用卡验证器。如果校验位与最后输入的数字匹配,那么它应该提醒用户它是有效的。否则,说它无效。目前,我的总和(总计)显示为 NaN 时出现错误。我认为这是代码的唯一问题。

<input type="number" id="creditCard" placeholder="0000 0000 0000 0000">
<input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">
function checkNumber() 
    let number = document.getElementById("creditCard").value;
    let multiplier = "212121212121212";
    let multipliedNumber;
    let multipliedString;

    if (number.length != 16) 
        alert("Please enter a Credit Card number that is 16 digits in length.");
     else 
        for (count = 0; count < number.length - 1; count++) 
            multipliedNumber = number[count] * multiplier[count];
            console.log(multipliedNumber);
            if (multipliedNumber > 9) 
                multipliedNumber = multipliedNumber[0] + multipliedNumber[1];
                multipliedString = multipliedString + multipliedNumber;
             else 
                multipliedString = multipliedString + multipliedNumber;

            
        
        console.log(multipliedString);
        let checkDigit = 10 - (multipliedString % 10);

        if (checkDigit == number[15]) 
            alert(`$number is a valid Credit Card number.`);
         else 
            alert(`$number is not a valid Credit Card number.`);
        
    

【问题讨论】:

multiplier 是一个字符串。 multiplier[count] 是一个字符串。 number 是一个字符串。 number[count] 是一个字符串。当您将字符串与字符串相乘时,您期望会发生什么? How to debug small programs 我可以添加 parseInt Trincot 已经解释了您的代码存在的问题。但您也可以查看已经可用的many other Luhn Algorithm JS questions。其中许多不共享 16 位限制。我对我不久前写的an answer 非常满意。 【参考方案1】:

有几个问题:

multipliedNumber 是一个产品,所以它是一个数字类型。因此,访问像[0][1] 这样的属性,只会评估为undefined。要么先将该值转换为字符串,要么(更好地)使用算术来提取两个数字:

multipliedNumber = multipliedNumber % 10 + Math.floor(multipliedNumber/10);

multipliedString 未初始化,因此向其中添加内容不会产生预期的结果。其次,你将它定义为一个字符串,但它应该是一个数字,就像 Luhn 的算法一样,你应该对结果数字求和,而不是连接它们。所以像这样初始化一个变量:

sum = 0;

...并像以前一样使用它——尽管您可以从+= 运算符中受益,并且由于两种情况的操作相同,您可以在if..else 块之外执行它。

当模运算计算结果为 0 时,校验位的计算是错误的:10 - (multipliedString % 10) 然后返回 10,但在这种情况下校验位应该是 0。只处理最后一个数字要容易得多在循环中,然后检查您是否达到了 10 的倍数。这也是 Wikipedia 上解释算法的方式@

修正版:

function checkNumber() 
    let number = document.getElementById("creditCard").value;
    let multiplier = "2121212121212121";  // One more character added...
    let multipliedNumber;
    let sum = 0 // Initialise it as a number.

    if (number.length != 16) 
        console.log("Please enter a Credit Card number that is 16 digits in length.");
     else 
        for (count = 0; count < number.length; count++)  // Include last digit in loop
            multipliedNumber = number[count] * multiplier[count];
            if (multipliedNumber > 9) 
                // Use arithmetic to add the two digits
                multipliedNumber = multipliedNumber % 10 + Math.floor(multipliedNumber/10);
            
            sum += multipliedNumber;
        
        let check = sum % 10; // Simpler now because all digits were processed
        if (check == 0)  // Sum is multiple of 10
            console.log(`$number is a valid Credit Card number.`);
         else 
            console.log(`$number is not a valid Credit Card number.`);
        
    
<input type="number" id="creditCard" placeholder="0000 0000 0000 0000">
<input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">

【讨论】:

以上是关于如何使用 Luhn 算法创建信用卡验证器?的主要内容,如果未能解决你的问题,请参考以下文章

LUHN 信用卡验证在有效卡号上失败

如何使用 notepad++ 搜索 16 位长字符串(Luhn 算法)?

iPhone Sdk 中的信用卡验证算法

信用卡号码的 Luhn 或 Verhoeff 算法

信用卡号验证 用c++如何解决?

C:信用卡号码检查器/ Luhn 算法