2

I'm trying to port a Luhm algorithm implementation I have that's in C# to JavaScript. I got it ported over and I thought it was working, but I can't get legitimate cards to validate. My AMEX validates fine, but my two VISAs refuse to do so. Here's the code:

luhn = function (number) {
    var _deltas = [0, 1, 2, 3, 4, -4, -3, -2, -1, 0],
        _checksum = 0,
        _digits = [],
        i,
        j;

    while (number != 0) {
        _digits.push(parseInt((number % 10), 10));

        number = parseInt((number / 10), 10);
    }

    for (i = (_digits.length - 1), j = _digits.length; i > -1; i--) {
        _digit = _digits[i];
        _checksum += _digit;
        _checksum += ((((i - j) % 2) === 0) ? _deltas[_digit] : 0);
    }

    return ((_checksum % 10) === 0);
};

Can someone point me in the right direction on what's wrong? I thought this worked fine in the C# version, but now I'm having doubts... Thanks in advance!

Gup3rSuR4c
  • 9,145
  • 10
  • 68
  • 126
  • Hint: `alert(parseInt("54511187504546384725", 10))` and [the answer](http://stackoverflow.com/a/12397870/265712). – meze Feb 16 '13 at 01:16
  • This works with the examples here: http://en.wikipedia.org/wiki/Luhn_algorithm but may not for larger numbers. – Aram Kocharyan Feb 16 '13 at 01:22

3 Answers3

0
  <script>
      // takes the form field value and returns true on valid number
    function valid_credit_card(value) {
      // accept only digits, dashes or spaces
        if (/[^0-9-\s]+/.test(value)) return false;

        // The Luhn Algorithm. It's so pretty.
        var nCheck = 0, nDigit = 0, bEven = false;
        value = value.replace(/\D/g, "");

        for (var n = value.length - 1; n >= 0; n--) {
            var cDigit = value.charAt(n),
                  nDigit = parseInt(cDigit, 10);

            if (bEven) {
                if ((nDigit *= 2) > 9) nDigit -= 9;
            }

            nCheck += nDigit;
            bEven = !bEven;
        }

        return (nCheck % 10) == 0;
    }

    console.log(valid_credit_card("5610591081018250"),"valid_credit_card Validation");
  </script>

Best Solution here

with all test cases passed according to

and the credit goes to

Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215
0

For others looking, below is a solution I submitted for a test :)

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

Hope this helps. Mitch - from https://spangle.com.au

Spangle
  • 762
  • 1
  • 5
  • 14
0

This solution accepts an array as a parameter. If its valid returns true and if its invalid returns false.

function validateCred(arr) {
    let sumArray = [];
    let numHolder = null;
    let everySecondNumber = 1;
    for (let i = arr.length - 1; i >= 0; i--) {
        if (everySecondNumber % 2 === 0) {
                numHolder = arr[i] * 2;
            if (numHolder > 9) {
                numHolder -= 9;
            }
        } else {
            numHolder = arr[i];
        }
        sumArray.push(numHolder);
        everySecondNumber++;
    }
    totalSum = sumArray.reduce((acc,val) => acc + val, 0);
    if (totalSum % 10 == 0) {
        return true;
    } else {
        return false;
    }
}
Daniel B
  • 39
  • 6