I’m currently implementing a Luhn algorithm on javascript:
const validateCred = arr => {
let sum = 0, cardNum = [...arr]
const lastCardNum = cardNum.pop()
cardNum.reverse()
cardNum.forEach((element, index)=> index % 2 === 0 ? sum+=element: element*2 > 9 ? sum+=element*2-9: sum+=element*2)
return sum % 10 === lastCardNum ? true: false
}
The Luhn Formula:
- Drop the last digit from the number. The last digit is what we want to check against
Reverse the numbers - Multiply the digits in odd positions (1, 3, 5, etc.) by 2 and subtract 9 to all any result higher than 9
- Add all the numbers together
- The check digit (the last number of the card) is the amount that you would need to add to get a multiple of 10 (Modulo 10)
I’m trying to test the following code but it returns true instead of false:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]; // actually a valid card number
console.log(validateCred(valid1)) // returns false :/
For some reason the sum of all numbers is 66 and obviously the modulo 10 of it is 6 and not 8
edit: Well I just modified the function to the way I know
const validateCred = arr => {
let sum = 0, cardNum = [...arr]
cardNum.forEach((element, index)=> index % 2 !== 0 ? sum+=element: element*2 > 9 ? sum+=element*2-9: sum+=element*2)
return sum % 10 === 0 ? true: false
}
I would appreciate if someone explains why have you to reverse the array? (For me is useless)
2
Answers
your algorithm is wrong, you need to test
(10 - sum) === lastCardNum
(see wikipedia)I also think your sum calculation is wrong…
I made a new one, according to Wikipedia !
https://en.wikipedia.org/wiki/Luhn_algorithm
PS: testing
v<5
means(v *2) < 10
But according to rosettacode.org on "Luhn test of credit card numbers"
I made this one, whose accept your card code values :
Step 2 of Wikipedia’s description
While we could do using a combination of array length and current index to determine whether or not to double a number, it’s easier to read and write by reversing and using
index % 2 === 0
.The reason you’re not seeing a difference whether you reverse or not is that you are testing with an even number of digits, as modern credit cards have. If there were an odd number and you didn’t reverse, you would be doubling the wrong digits. I have no idea if 16-digit CC numbers was the norm when the algorithm was created. But the algorithm is designed for an arbitrary number of digits.