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

How can I create a credit card validator using Luhn's algorithm?

我正在尝试使用 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.`);
        }
    }
}

有几个问题:

  • multipliedNumber是乘积,所以是数字类型。因此,访问 [0][1] 之类的属性,只会评估为 undefined。要么先将该值转换为字符串,要么(更好)使用算术提取两位数:

    multipliedNumber = multipliedNumber % 10 + Math.floor(multipliedNumber/10);
    
  • multipliedString 未初始化,因此向其添加内容不会产生预期的结果。其次,你将它定义为一个字符串,但它应该是一个数字,就像 Luhn 算法一样,你应该对结果数字求和,而不是将它们连接起来。所以像这样初始化一个变量:

    sum = 0;
    

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

  • 当模运算计算结果为 0 时校验位的计算是错误的:10 - (multipliedString % 10) 然后 returns 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()">