简体   繁体   English

为什么 Luhn 算法的这种实现不起作用?

[英]Why is this implementation of Luhn's algorithm not working?

I was creating a function for Luhn's algorithm in Javascript.我正在用 Javascript 为 Luhn 算法创建一个函数。 Here is my code:这是我的代码:

// All valid credit card numbers
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
const valid4 = [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5];
const valid5 = [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6];

// All invalid credit card numbers
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const invalid2 = [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];

// Can be either valid or invalid
const mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];

// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];


// Add your functions below:
function validateCred(arr){
  let newArr = [];
  newArr.push(arr[arr.length - 1]);
  for(let i = arr.length - 2; i >= 0; i--){
    let x = arr[i];
    // console.log(x);
    x *= 2;
    if(x > 9){
      x -= 9;
    }
    // console.log(x);
    newArr.push(x);
    // console.log(newArr);
  } 
  // console.log(newArr);
   let sum = 0;
   newArr.forEach(num => sum += num);
   console.log(sum);
//    if(sum % 10 === 0){
//     return true;
//   } else {
//      return false;
//  }
  return newArr;
}
console.log(validateCred(valid1));

This is not my original code, but as you can see validateCred is my function.这不是我的原始代码,但正如您所看到的, validateCred是我的函数。 The if statement is actually supposed to give a result of true, but it is giving false, so I was wondering where I went wrong. if 语句实际上应该给出 true 的结果,但它给出的是 false,所以我想知道我哪里出错了。 The console.log's in here were helping me figure out what went wrong, so here is the output of them.此处的 console.log 帮助我找出出了什么问题,所以这是它们的输出。 I cut the code to see what the function was doing with the array, I checked and everything was good.我剪切了代码以查看函数对数组做了什么,我检查了一切都很好。 Even the sum was working.甚至总和也在起作用。 So I was left wondering whether the array is wrong, but when I inputed the same array in GeeksForGeeks's implementation, It gave true!所以我想知道数组是否错误,但是当我在 GeeksForGeeks 的实现中输入相同的数组时,它给出了正确的! So what went wrong?那么出了什么问题呢?

I don't want to take Niet's credits, so if he posts his comments as an anwser, you should accept his.我不想接受 Niet 的功劳,所以如果他发表评论作为 anwser,你应该接受他的。 I'm posting this only two show two shorter alternatives using Array.prototype.reduce我发布的只有两个使用Array.prototype.reduce显示两个较短的替代方案

The main problem with your algorithm is (as Niet already said) you are doubling each digit, instead of only every other digit.你的算法的主要问题是(正如 Niet 已经说过的)你将每个数字加倍,而不是每隔一个数字。

Variant 1 with reversing the card number变体 1 反转卡号

function checkCard(arr) {
  return arr.slice().reverse() 
    .reduce((a, c, i) => a + (i % 2 == 0
      ? c
      : (c < 5 ? 2 * c : 2 * c - 9)), 
      0) % 10 == 0;
}

I used arr.slice().reverse() because reverse works in place.我使用了arr.slice().reverse()因为reverse就位。 So to keep arr in the original order, copy it first.所以要保持arr的原始顺序,请先复制它。 reduce will then sum up the digits.然后reduce将总结数字。 For every even index (0,2,4,...) in the reversed array it will just add the current digit c .对于反向数组中的每个偶数索引 (0,2,4,...),它只会添加当前数字c For every odd (1,3,5,...) index, it will add either 2*c or 2*c-9 , depending on whether 2*c > 9 .对于每个奇数 (1,3,5,...) 索引,它将添加2*c2*c-9 ,具体取决于2*c > 9

Variant 2 without reversing the card number不颠倒卡号的变体2

function checkCard2(arr) {
  const p = arr.length % 2
  return arr.reduce((a,c,i) => a + (i % 2 != p 
    ? c
    :  (c < 5 ? 2 * c : 2 * c - 9)),
    0) % 10 == 0;
}

Because Luhn's original algorithm starts couting from the rightmost digit, if we start from the leftmost digit (ie without reversing the number), we have to act differently on numbers of even or odd length.因为 Luhn 的原始算法从最右边的数字开始计算,如果我们从最左边的数字开始(即不反转数字),我们必须对偶数或奇数长度的数字采取不同的行动。 For numbers of odd length, we must double the digits at odd indexes (1,3,5,...), for even length we must double the digits at even indexes (0,2,4,...).对于奇数长度的数字,我们必须将奇数索引 (1,3,5,...) 处的数字加倍,对于偶数长度,我们必须将偶数索引 (0,2,4,...) 处的数字加倍。 That's what the p is for.这就是p的用途。 It will be 0 for even length, and 1 for odd length.偶数长度为0 ,奇数长度为1 So if i % 2 == p we must double the current digit, otherwise not.因此,如果i % 2 == p我们必须将当前数字加倍,否则不会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM