【发布时间】:2021-05-16 06:37:09
【问题描述】:
我目前正在学习 Codecademy 的全栈工程师课程,到目前为止,我对它非常满意,发现新事物,自己解决问题,但这是我进步的一个严重障碍,我只能这样做'似乎无法识别此逻辑的问题。我并不是要质疑 Luhn 的算法,但我真的需要对此进行澄清……
所以我的问题是,该算法将我的所有数组都返回为有效,我的代码如下(由 codecademy 提供的数组):
// 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];
以及我实现算法的函数:
const validateCred = arr => {
let checkSum = 0;
let ifEvenDouble = 0;
arr.push(checkSum);
//Iterate through array, double what is needed
for(let i = arr.length - 2; i >= 0; i--){
console.log(ifEvenDouble);
//If ifEvenDouble is even, we are at the 'other' cell
if((ifEvenDouble % 2) === 0){
let doubled = arr[i] * 2;
//If doubled digit is greater than 9, store sum of individual digits
//Convert the doubled number to a string then extract each member and convert back to number for calculation, add to checkSum and skip to next iteration, otherwise, add arr[i]
let newDigit = 0;
if(doubled > 9){
newDigit = Number(doubled.toString()[0]) + Number(doubled.toString()[1]);
//Add doubled & split digit to total and continue the loop
checkSum += newDigit;
ifEvenDouble++;
continue;
}
//Add doubled digit less than 9 to total and continue the loop
checkSum += doubled;
ifEvenDouble++;
continue;
}
//Add current array member to total
checkSum += arr[i];
ifEvenDouble++;
}//End for loop
console.log(checkSum);
const checkDigit = (checkSum * 9) % 10;
const totalSum = checkDigit + checkSum;
if(totalSum % 10 === 0){
console.log('Valid');
return true;
} else {
console.log('Invalid');
return false;
}
};
validateCred(invalid1); // -> Output: Valid
据我了解,我的总和总是将是 10 的倍数,如果我从 10 中减去我的个位,将其添加到我的校验和是总是 给我 10 的倍数。我错了吗?
编辑:我一直在尝试调试它,但我做的越多,离核心算法就越远。
Edit(2):感谢下面的人,我认为我的问题是生成我自己的校验位,而不是使用已经提供的校验位?我的困惑是,通过阅读有关此的*页面,它说:
'计算校验位的例子: 假设一个帐号“7992739871”的示例将添加一个校验位,使其格式为 7992739871x'
然后他们继续用除 x 之外的数字进行所有计算,我认为这是现在主要的困惑。
【问题讨论】:
-
真正的问题是什么?有什么错误吗?到目前为止,您自己尝试过什么来解决/调试此问题?
-
我的问题是,根据该算法,本应无效的 cc 号码返回有效。在过去的 3 个小时里,我一直在尝试调试它,但我最终偏离了核心算法,而重点是实现它。
-
找到一个返回错误结果的循环,单步执行循环并检查出错的位置和时间。
-
“从 arr.length - 2 开始,它是倒数第二个数组成员” - 这是正确的,因为您必须跳过最右边(最后一个)元素,它位于索引
array.length - 1处,使array.length - 2处的元素成为第一个使用的元素。但是添加校验和后,您就弄乱了这些数字。 -
@Andreas 这就是我的想法,但里面有
continue。让人很难跟上。正如我的回答所说,对于如此简单的事情,实现起来过于复杂。
标签: javascript arrays algorithm credit-card luhn