首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Luhn算法逻辑

Luhn算法逻辑
EN

Stack Overflow用户
提问于 2021-02-12 13:51:59
回答 1查看 416关注 0票数 0

我目前正在读Codecademy的全部堆栈工程师课程,到目前为止,我一直对此非常满意,发现新事物,自己解决问题,但这是我前进过程中的一个严重障碍,因为我似乎无法用这种逻辑来识别问题所在。我不想质疑卢恩的算法,但我真的需要澄清一下.

因此,我的问题是,算法将我的所有数组返回为有效,我的代码如下所示(codecademy提供的数组):

代码语言:javascript
复制
// 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];

我的函数实现了算法:

代码语言:javascript
复制
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

据我所知,我的totalSum是总是将是10的倍数,如果我从10减去我的单位数字,把它加到我的checkSum中,总是会给我10的倍数。我错了吗?

编辑:我已经尝试过调试它,但是我做的越多,就越远离核心算法。

编辑(2):所以,感谢下面的人,我认为我的问题是生成我自己的支票数字,而不是使用已经提供的数字?我感到困惑的是,从维基百科的页面上可以看出:

“用于计算支票数字的示例:假设一个帐号"7992739871”的示例,其中将添加一个支票数字,使其为7992739871x‘

然后他们用x以外的数字进行所有的计算,我认为这是现在的主要混淆。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-12 14:10:03

你的算法太复杂了。维基百科简洁地描述了它,只需实现以下三个步骤

  1. 从最右边的数字(不包括选中的数字)向左移动,是每秒钟数字的两倍。检查数字既不加倍,也不包括在此计算中;第一个数字加倍是位于支票数字左侧的数字。如果加倍运算的结果大于9(例如,8×2= 16),则添加结果的数字(例如,16: 1+6= 7,18: 1+8= 9)或从结果中相应地减去9(例如,16: 16−9= 7,18: 18−9= 9)。
  2. 取所有数字之和(包括检查数字)。
  3. 如果总模10等于0(如果总数以零结尾),那么根据Luhn公式,这个数字是有效的;否则它是无效的。

我还认为你误解了支票数字是什么。您似乎将它作为0附加到数组中,并试图在最后计算它。数字里已经有了--这是最后一个数字。

代码语言:javascript
复制
const validateCred = arr => {

   let doubleIt = true;
   let sum = 0;
   // From the rightmost digit excluding check digit...
   for(let i = arr.length - 2; i >= 0; i--){
        
        if(doubleIt){
          let doubled = arr[i] * 2;
         
          if(doubled > 9){
            doubled -= 9
          }
          sum += doubled
        }
        else {
          sum += arr[i]
        }
        doubleIt = !doubleIt;

    }

    // Add the check digit to the sum
    sum += arr[arr.length-1];

    // If sum is divisible by 10 it is valid
    if(sum % 10 === 0){
      console.log('Valid');
      return true;
    } else {
      console.log('Invalid');
      return false;
    }
};

const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
validateCred(invalid1);
validateCred(valid1);

你出错的地方主要围绕着支票数字的使用。您似乎在计算它,而它只是数组中的最后一个元素。下面的代码片段更接近您的原始代码,只是不需要计算检查数字。

代码语言:javascript
复制
const validateCred = arr => {

    let ifEvenDouble = 0;
   let checkSum=0
    //Iterate through array, double what is needed

    for(let i = arr.length - 2; i >= 0; i--){

      //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

    const checkDigit = arr[arr.length-1]
    const totalSum = checkDigit + checkSum;

    if(totalSum % 10 === 0){
      console.log('Valid');
      return true;
    } else {
      console.log('Invalid');
      return false;
    }
};


const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
validateCred(invalid1);
validateCred(valid1);

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66173063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档