Skip to content

Instantly share code, notes, and snippets.

@pombadev
Last active October 12, 2016 04:51
Show Gist options
  • Save pombadev/c23128c8c4b459a54c74701c9f5f2669 to your computer and use it in GitHub Desktop.
Save pombadev/c23128c8c4b459a54c74701c9f5f2669 to your computer and use it in GitHub Desktop.
Implementation of The Luhn Algorithm
/*
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