I am trying to create a simple credit card validator using Luhn's algorithm. If the check digit matches the last inputted number, then it should alert the user that it is valid. Else, say that it isn't valid. Currently, I am getting an error with my sum (total) coming up as NaN. I assume that is the only problem with the code.
<input type="number" id="creditCard" placeholder="0000 0000 0000 0000">
<input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">
function checkNumber() {
let number = document.getElementById("creditCard").value;
let multiplier = "212121212121212";
let multipliedNumber;
let multipliedString;
if (number.length != 16) {
alert("Please enter a Credit Card number that is 16 digits in length.");
} else {
for (count = 0; count < number.length - 1; count ) {
multipliedNumber = number[count] * multiplier[count];
console.log(multipliedNumber);
if (multipliedNumber > 9) {
multipliedNumber = multipliedNumber[0] multipliedNumber[1];
multipliedString = multipliedString multipliedNumber;
} else {
multipliedString = multipliedString multipliedNumber;
}
}
console.log(multipliedString);
let checkDigit = 10 - (multipliedString % 10);
if (checkDigit == number[15]) {
alert(`${number} is a valid Credit Card number.`);
} else {
alert(`${number} is not a valid Credit Card number.`);
}
}
}
CodePudding user response:
There are several issues:
multipliedNumber
is a product, so it is a number type. Therefore accessing properties like[0]
or[1]
on it, will just evaluate toundefined
. Either turn that value to string first, or (better) use arithmetic to extract the two digits:multipliedNumber = multipliedNumber % 10 Math.floor(multipliedNumber/10);
multipliedString
is not initialised, so adding things to it will not give the desired outcome. Secondly, you define it as a string, but it should be a number, as with Luhn's algorithm you are supposed to sum up the resulting digits, not concatenate them. So initialise a variable like this:sum = 0;
... and use it like you did -- although you could benefit from the
=
operator, and since the operation is the same for both cases, you can do it outside of theif..else
blocks.The calculation of the check digit is wrong when the modulo operation evaluates to 0:
10 - (multipliedString % 10)
then returns 10, but in that case the check digit is supposed to be 0. It is much easier to just treat that last digit also in the loop and then check that you have reached a multiple of 10. This is also how the algorithm is explained on Wikipedia
Corrected version:
function checkNumber() {
let number = document.getElementById("creditCard").value;
let multiplier = "2121212121212121"; // One more character added...
let multipliedNumber;
let sum = 0 // Initialise it as a number.
if (number.length != 16) {
console.log("Please enter a Credit Card number that is 16 digits in length.");
} else {
for (count = 0; count < number.length; count ) { // Include last digit in loop
multipliedNumber = number[count] * multiplier[count];
if (multipliedNumber > 9) {
// Use arithmetic to add the two digits
multipliedNumber = multipliedNumber % 10 Math.floor(multipliedNumber/10);
}
sum = multipliedNumber;
}
let check = sum % 10; // Simpler now because all digits were processed
if (check == 0) { // Sum is multiple of 10
console.log(`${number} is a valid Credit Card number.`);
} else {
console.log(`${number} is not a valid Credit Card number.`);
}
}
}
<input type="number" id="creditCard" placeholder="0000 0000 0000 0000">
<input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">