Last active
October 12, 2016 04:51
-
-
Save pombadev/c23128c8c4b459a54c74701c9f5f2669 to your computer and use it in GitHub Desktop.
Implementation of The Luhn Algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Implementation of The Luhn Algorithm (https://en.wikipedia.org/wiki/Luhn_algorithm) | |
*/ | |
function validate(n) { | |
/** | |
* Check if the given number is of valid type | |
*/ | |
if (!n || typeof n !== 'number') { | |
// purposely not checking the length of the string | |
return false | |
} | |
/** | |
* Placeholders | |
* @type {Array} doubled | |
* @type {Number} finalSum | |
*/ | |
let doubled = [], | |
finalSum = 0; | |
const | |
/** | |
* Takes number and returns the number doubled | |
* @param {[Number]} num | |
* @return {[Number]} | |
*/ | |
double = num => num + num, | |
/** | |
* Checks if given number is even | |
* @param {[Num]} num | |
* @return {[Boolean]} | |
*/ | |
isEven = num => num % 2 === 0, | |
/** | |
* Convert the given number to array for easier looping and | |
* individual element's manipulation | |
* @type {[Array]} | |
*/ | |
stringify = n.toString().split(''), | |
/** | |
* Takes array and boolean and increments its elements | |
* @param {[Array]} array | |
* @param {[Boolean]} lengthIsOdd | |
* @return {[Boolean]} | |
*/ | |
incrementor = (array, lengthIsOdd) => { | |
/* | |
Adding an dummy element to array to start index from 1. | |
If lengthIsOdd === true, double every other digit starting with the second | |
else double every other digit starting with the first. | |
*/ | |
array.unshift(0) | |
array.map((el, idx) => { | |
if (lengthIsOdd ? isEven(idx) : !isEven(idx)) { | |
doubled.push(double(Number(array[idx++]))) | |
} else { | |
doubled.push(Number(array[idx])) | |
} | |
}) | |
/* Restore the array */ | |
doubled.shift() | |
}, | |
/** | |
* If element is a double digit number, substract it by 9 | |
* and return it. | |
* @param {[Number]} el | |
* @return {[Number]} | |
*/ | |
normalizeElements = el => el > 9 ? el - 9 : el, | |
/** | |
* Add all the elements | |
* @param {[Number]} sum [Initial value] | |
* @param {[Number]} el [Supplied elements] | |
* @return {[Number]} | |
*/ | |
addAllElements = (sum, el) => sum = sum + el | |
if (isEven(stringify.length)) { | |
incrementor(stringify, false) | |
} else { | |
incrementor(stringify, true) | |
} | |
finalSum = doubled | |
.map(el => normalizeElements(el)) | |
.reduce(addAllElements, 0) | |
/* Finally, take that sum and divide it by 10. If the remainder equals zero, the original credit card number is valid. */ | |
return finalSum % 10 === 0 | |
} | |
// console.log('Final', validate(5200828282828210)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment