鲁恩算法逻辑 [英] Luhn Algorithm Logic

查看:60
本文介绍了鲁恩算法逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在学习Codecademy的Full Stack Engineer课程,到目前为止,我一直对它非常满意,可以自己发现新事物,解决问题,但这是我前进的一个严重障碍,因为我可以做到.似乎无法确定这种逻辑的问题.我并不是要质疑Luhn的算法,但是我真的需要对此进行澄清...

I am currently going through Codecademy's Full Stack Engineer course, up until now I have been perfectly fine with it, discovering new things, working out problems on my own, but this is a serious roadblock in my progression as I just can't seem to identify the problem with this logic. I don't mean to question Luhn's algorithm but seriously I need some clarification on this...

所以我的问题是,该算法将所有我的数组都返回为有效数组,下面是我的代码(codecademy提供的数组):

So my problem is, that the algorithm is returning all my arrays as valid, my code is below (arrays provided by 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

据我了解,我的totalSum总是 ,如果我要从10减去单位数字,则将其加到我的checkSum总是 >会给我10的倍数.我错了吗?

From my understanding, my totalSum is always going to be a multiple of 10, if I'm subtracting my unit digit from 10, adding it to my checkSum is always going to give me a multiple of 10. Am I wrong?

我已经在尝试调试它,但是我做的越多,离我迷恋的核心算法就越远.

I have been attempting to debug this already but the more I do the further away from the core algorithm I stray.

Edit(2):感谢以下人员,我认为我的问题是生成自己的校验位,而不是使用已经提供的校验位?我的困惑是,从阅读此书的维基百科页面上,它会说:

Edit(2): So thanks to the guys below, I think my issue was generating my own check digit as opposed to using one already provided? My confusion is that from reading the wikipedia page on this, it says:

'计算校验位的示例:假设一个例子的账户号"7992739871"被示于图2中.将添加一个校验位,使其格式为7992739871x'

'Example for computing check digit: Assume an example of an account number "7992739871" that will have a check digit added, making it of the form 7992739871x'

然后他们继续使用除x之外的数字进行所有计算,我认为这是目前的主要困惑.

And then they proceeded to do all their calculations with the numbers besides x, i think this is the main confusion now.

推荐答案

您的算法不必要地复杂. Wikipedia 对其进行了简要描述,只需执行3个步骤

Your algorithm is unnecessarily complicated. Wikipedia describes it succinctly, just implement the 3 steps

  1. 从最右边的数字(不包括校验数字)向左移动,使第二个数字的值翻倍.校验位既不加倍也不包括在此计算中;加倍的第一个数字是紧接在校验数字左边的数字.如果此加倍运算的结果大于9(例如8×2 = 16),则将结果的数字相加(例如16:16:1 + 6 = 7、18:1 + 8 = 9)或等效地,从结果中减去9(例如16:16-9 = 7、18:18-9 = 9).
  2. 取所有数字(包括校验位)的总和.
  3. 如果模10的总和等于0(如果总数以零结尾),则根据Luhn公式,该数字有效;否则,该数字有效.否则无效.

我还认为您误解了校验位是什么.您似乎将其作为 0 附加到数组,并尝试在最后进行计算.数字中已经存在-这是最后一位数字.

I also think you misunderstood what the check digit is. You appeared to be appending it to the array as 0, and trying to calculate it at the end. It's already there in the number - it's the final digit.

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);

您出错的地方主要是校验位的使用.您似乎正在计算它,而它已经作为数组中的最后一个元素存在了.下面的代码段与您的原始代码非常接近,只是无需计算校验位.

The places you went wrong were mainly around the use of the check digit. You appeared to be calculating it whereas its already there as just the final element in the array. The below snippet is a lot closer to your original, just without the calculation of check digit.

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);

这篇关于鲁恩算法逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆