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!

2
  • Hint: alert(parseInt("54511187504546384725", 10)) and the answer. Commented Feb 16, 2013 at 1:16
  • This works with the examples here: en.wikipedia.org/wiki/Luhn_algorithm but may not for larger numbers. Commented Feb 16, 2013 at 1:22

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.