1

我刚开始学习 Javascript 时非常糟糕。我正在对一张 16 位数的信用卡进行 Luhn 检查。这让我发疯了,如果有人看过它并能给我一些帮助,我将不胜感激。

<script>
var creditNum;
var valid = new Boolean(true);

creditNum = prompt("Enter your credit card number: ");

if((creditNum==null)||(creditNum=="")){
    valid = false;
    alert("Invalid Number!\nThere was no input.");
}else if(creditNum.length!=16){
    valid = false;
    alert("Invalid Number!\nThe number is the wrong length.");
}
//Luhn check
var c;
var digitOne;
var digitTwo;
var numSum;
for(i=0;i<16;i+2){
    c = creditNum.slice(i,i+1);
    if(c.length==2){
        digitOne = c.slice(0,1);
        digitTwo = c.slice(1,2);
        numSum = numSum + (digitOne + digitTwo);
    }else{
        numSum = numSum + c;
    }
}
if((numSum%10)!=0){
    alert("Invalid Number!");
}else{
    alert("Credit Card Accepted!");
}
</script>
4

3 回答 3

0

您的代码中的直接问题是您的for循环。 i+2不是适当的第三项。从上下文中,您正在寻找i = i + 2,您可以将其简写为i += 2

看来您的算法是“取 16 位数字,将它们变成 8 对,将它们加在一起,看看总和是否可以被 10 整除”。如果是这种情况,您可以大大简化您的循环 - 您无需查看十位,只需查看单位的位置。

你的循环可能看起来像这样并做同样的事情:

for (i = 1; i < 16; i +=2) {
    numSum += +creditNum[i];
}

另外,请注意,只要您处理的是字符串,您根本不需要对任何内容进行切片 - 只需使用数组表示法来获取每个字符。

+在前面加了一个creditNum。javascript 的问题之一是它将字符串视为字符串,因此如果您有字符串“1”和字符串“3”并添加它们,您将连接并得到“13”而不是 4。加号强制字符串是一个数字,所以你会得到正确的结果。

循环的第三项是我看到的唯一明显的错误。我实际上并不知道 Luhn 算法,所以从代码的上下文中推断出其余的。

编辑

好吧,如果您发布了Luhn 算法是什么,那将会有所帮助。很有可能,如果您至少可以清楚地表达它,您可以帮助我们帮助您编写代码。

这就是你想要的。

// Luhn check
function luhnCheck(sixteenDigitString) {
    var numSum = 0;
    var value;
    for (var i = 0; i < 16; ++i) {
        if (i % 2 == 0) {
            value = 2 * sixteenDigitString[i];
            if (value >= 10) {
                value = (Math.floor(value / 10) + value % 10);
            }
        } else {
            value = +sixteenDigitString[i];
        }
        numSum += value;
    }
    return (numSum % 10 == 0);
} 

alert(luhnCheck("4111111111111111"));

这样做是遍历所有数字,保持偶数索引不变,但将奇数索引加倍。如果加倍超过 9,则根据 wikipedia 中所述的算法,将两位数的值相加。

小提琴

注意:我测试的号码不是我的信用卡号码,但它是一个众所周知的号码,您可以使用它来通过正确编码的 Luhn 验证。

于 2013-10-08T14:01:32.707 回答
0

我的以下解决方案也适用于 AmEx。我不久前提交了它进行代码测试。希望能帮助到你 :)

function validateCard(num){
    var oddSum = 0;
    var evenSum = 0;
    var numToString = num.toString().split("");
    for(var i = 0; i < numToString.length; i++){
      if(i % 2 === 0){
        if(numToString[i] * 2 >= 10){
          evenSum += ((numToString[i] * 2) - 9 );
        } else {
          evenSum += numToString[i] * 2;
        }
      } else {
        oddSum += parseInt(numToString[i]);
      }
    }
    return (oddSum + evenSum) % 10 === 0;
  }
console.log(validateCard(41111111111111111));

享受 - 来自https://spangle.com.au的 Mitch

于 2019-02-04T05:22:11.183 回答
0

@Spangle,当您在这里使用偶数和奇数时,您已经在考虑索引 0 是偶数了吗?因此,您将索引 0、2 等处的数字加倍,而不是第二个位置、第四个等......这是故意的吗?与我正在使用的另一种算法相比,它在这里返回的某些卡的验证不一致。试试 AmEx 的 378282246310005。

于 2021-06-23T20:36:00.703 回答