Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Luhn validation algorithm
* Luhn algorithm in JavaScript: validate credit card number supplied as string of numbers
* @author ShirtlessKirk. Copyright (c) 2012.
* @license WTFPL (
var luhnChk = (function (arr) {
return function (ccNum) {
len = ccNum.length,
bit = 1,
sum = 0,
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]));

Closure compiled version (updated Feb 11, 2015):

var luhnChk=function(a){return function(c){for(var l=c.length,b=1,s=0,v;l;)v=parseInt(c.charAt(--l),10),s+=(b^=1)?a[v]:v;return s&&0===s%10}}([0,2,4,6,8,1,3,5,7,9]);

This is awesome and apparently the most performant luhncheck in js (in chrome at least). Not sure if you have seen this:


wow! awesome! not only fast, but also beautiful code <3
thank you, dude




Woww! So far the Fastest Algorithm i've tried! :+1:


Well done!


Fuckk Yeahhh!!!


Spot of code golf: After reviewing subsequent edits on jsperf, I've tweaked the code. The test case is at if you want to check.

  • decrement now happens inline rather than during the while conditional check (I prefer that placement)
  • reduction of product array contents to just the doubled number value as you've already got the undoubled value (less to initialise, less to look up)
  • the use of a closure to use the product array as a parameter was intriguing
  • return statement reversed to utilise short-circuiting better (if a zero length string is sent in then the sum is 0, cosmetic really)

A variant on the jsperf page doesn't run parseInt() if using the undoubled value. Personally, I don't like using it in some places and not others so I always run it. That's why this code isn't the fastest...


Ummm, WOW. TY!!!!


I am new, any one can tell me how can i use this code?
I want to validate cards.
and this code can validate all type of cards?


+1 thanks!


@geniuscarpi: Use it as luhnChk("numberToValidate").


I'm a bit confused the reason for bit ^= 1, since it seems that bit never changes? (version Feb 11, 2015)


Using an adapted version of your luhn check in our validation


Hey, I passed a test with 7 digits 2222222. Isn't valid credit card has digits range from 12 to 19? is this a bug?


@tomByrer: yeah it does. ^= flips the value. It's a bitwise operator, not a Boolean one (see MDN page)

@CeleryCup: this is just a Luhn algorithm (see Wikipedia). Apart from checking for zero length strings there is no range checking as that is outside the scope of the method and checking for credit card number validity is just one application of it. For example, you could set up a login verification solution using identifier numbers that must pass Luhn to be valid.


I decided to adapt your code, but add support for creating a Luhn checksum. You can find the changes here:


MasterCard announced new bin ranges (222100 - 272099) in November 2014, and will be introduced into the payment eco-system on October 2016, not sure if this validates them, but I'm assuming it will.


There is a small issue regarding user input. The input MUST be a string, otherwise the return is always 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.