25 lines
667 B
JavaScript
25 lines
667 B
JavaScript
|
const R = require('ramda')
|
||
|
|
||
|
// Reference: https://en.wikipedia.org/wiki/Luhn_algorithm
|
||
|
|
||
|
module.exports = val => {
|
||
|
val = val.replace(/[-\s]/g, '')
|
||
|
return val.match(/^[0-9-\s]+$/) && luhnCheck(val)
|
||
|
}
|
||
|
|
||
|
const luhnCheck =
|
||
|
R.compose(
|
||
|
R.equals(0)
|
||
|
, R.modulo(R.__, 10)
|
||
|
, R.sum
|
||
|
, R.map(n => n > 9 ? n - 9 : n) // Subtract 9 from those digits greater than 9
|
||
|
, R.addIndex(R.map)((n, i) => i % 2 === 0 ? n : n * 2) // Double the value of every second digit
|
||
|
, R.map(ch => Number(ch))
|
||
|
, R.reverse)
|
||
|
|
||
|
/*
|
||
|
Luhn check in haskell:
|
||
|
luhn = (0 ==) . (`mod` 10) . sum . map (uncurry (+) . (`divMod` 10)) .
|
||
|
zipWith (*) (cycle [1,2]) . map digitToInt . reverse
|
||
|
*/
|