-
-
Save ShirtlessKirk/2134376 to your computer and use it in GitHub Desktop.
/** | |
* Luhn algorithm in JavaScript: validate credit card number supplied as string of numbers | |
* @author ShirtlessKirk. Copyright (c) 2012. | |
* @license WTFPL (http://www.wtfpl.net/txt/copying) | |
*/ | |
var luhnChk = (function (arr) { | |
return function (ccNum) { | |
var | |
len = ccNum.length, | |
bit = 1, | |
sum = 0, | |
val; | |
while (len) { | |
val = parseInt(ccNum.charAt(--len), 10); | |
sum += (bit ^= 1) ? arr[val] : val; | |
} | |
return sum && sum % 10 === 0; | |
}; | |
}([0, 2, 4, 6, 8, 1, 3, 5, 7, 9])); |
The luhn test is failing for the MasterCard BIN 2-Series (222100-272099)
Sample Master Card:
2221 0012 3412 3456,
Expiry : 12/18
@afixibiranchi I see that your issue was answered on http://planetcalc.com/2464/ . I'm guessing you used the "number" on the example card image of https://www.mastercard.us/en-us/issuers/get-support/2-series-bin-expansion.html where it would make sense to be an invalid number...
Wonderful! Thank you.
@ShirtlessKirk OMFG
Phil, dude, who could've imagined it'would be your implementation of Luhn check I'm gonna use?!
@ShirtlessKirk I'd like to use this luhn implementation, but my employer forbids software licensed under WTFPL. Can you relicense or dual-license under BSD or MIT?
Wonderful implementation. I worked a very basic solution to adapt this algorithm to TypeScript, feel free to use or comment on improvements:
`
public luhnAlgorithmCheck(ccNum) {
const arr = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
let len = ccNum.length;
let bit = 1;
let sum = 0;
let val;
while (len) {
val = parseInt(ccNum.charAt(--len), 10);
// tslint:disable-next-line:no-bitwise
sum += (bit ^= 1) ? arr[val] : val;
}
return sum && sum % 10 === 0;
}
`
Thanks for sharing the original code, @ShirtlessKirk
"12345678".split("").reverse().map(function(c, i) { return ((i%2==0 ? 1 : 2)*parseInt(c)) }).join("").split("").map((c) => parseInt(c)).reduce(function(sum, c) { return sum+=parseInt(c) })
I tested against https://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
76009244561 did not return true
But I'm not sure if this number is really valid. all luhn verification code seem to fail when I use this number.
@ShirtlessKirk What does the array at the end do?
}([0, 2, 4, 6, 8, 1, 3, 5, 7, 9]));
@jefelewis it's a lookup table. Basically, instead of calculating the summed result of the numbers that are doubled (every second digit from right) each time, the code uses the precalculated value stored in the array at the index of the digit in question.
For example, if the digit is 6, the summed double is 3 (6 * 2 = 12, 1 + 2 = 3). In the array, the value at index 6 (the original digit used as a reference) is set to 3.
@ShirtlessKirk Can this be implemented in Shopify or Woocommerce? How can you install it without having access to the payment iframe
Declarative/functional approach:
const checkLuhn = cardNumber => {
const sum = [...cardNumber].reduceRight((prev, curr, i, arr) =>
prev+= (i%2)?Number(arr[Number(curr)]):Number(curr)
,0);
return sum && sum % 10 === 0;
}
@carlosvega20 I'm a bit confused by Number(arr[Number(curr)])
expression and not sure if this works correctly for check
Can suggest instead smth like this:
const isLuhn = (cardNumber) => {
const checkSum = [...cardNumber].reduceRight((prev, curr, i, arr) => {
if(i % 2) {
return prev += Number(curr);
} else {
const d = Number(curr) * 2
return prev += d > 9 ? d - 9 : d
}
}, 0);
return checkSum && checkSum % 10 === 0
}
Wow, Impressive