Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Luhn validation algorithm
/**
* 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]));
@ShirtlessKirk

This comment has been minimized.

Show comment
Hide comment
@ShirtlessKirk

ShirtlessKirk Mar 20, 2012

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]);
Owner

ShirtlessKirk commented Mar 20, 2012

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]);
@parris

This comment has been minimized.

Show comment
Hide comment
@parris

parris Sep 24, 2012

This is awesome and apparently the most performant luhncheck in js (in chrome at least). Not sure if you have seen this: http://jsperf.com/credit-card-validator/7

parris commented Sep 24, 2012

This is awesome and apparently the most performant luhncheck in js (in chrome at least). Not sure if you have seen this: http://jsperf.com/credit-card-validator/7

@ondrek

This comment has been minimized.

Show comment
Hide comment
@ondrek

ondrek Oct 14, 2013

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

ondrek commented Oct 14, 2013

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

@storytime

This comment has been minimized.

Show comment
Hide comment

Awesome!

@MohamedAlaa

This comment has been minimized.

Show comment
Hide comment
@MohamedAlaa

MohamedAlaa Jul 10, 2014

Woww! So far the Fastest Algorithm i've tried! 👍

Woww! So far the Fastest Algorithm i've tried! 👍

@oPorks

This comment has been minimized.

Show comment
Hide comment
@oPorks

oPorks Jul 28, 2014

Well done!

oPorks commented Jul 28, 2014

Well done!

@lagden

This comment has been minimized.

Show comment
Hide comment
@lagden

lagden Aug 14, 2014

Fuckk Yeahhh!!!

lagden commented Aug 14, 2014

Fuckk Yeahhh!!!

@ShirtlessKirk

This comment has been minimized.

Show comment
Hide comment
@ShirtlessKirk

ShirtlessKirk Feb 11, 2015

Spot of code golf: After reviewing subsequent edits on jsperf, I've tweaked the code. The test case is at http://jsperf.com/credit-card-validator/16 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...

Owner

ShirtlessKirk commented Feb 11, 2015

Spot of code golf: After reviewing subsequent edits on jsperf, I've tweaked the code. The test case is at http://jsperf.com/credit-card-validator/16 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...

@ChadReitsma

This comment has been minimized.

Show comment
Hide comment
@ChadReitsma

ChadReitsma Mar 11, 2015

Ummm, WOW. TY!!!!

Ummm, WOW. TY!!!!

@geniuscapri

This comment has been minimized.

Show comment
Hide comment
@geniuscapri

geniuscapri May 5, 2015

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?

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?

@lebiru

This comment has been minimized.

Show comment
Hide comment
@lebiru

lebiru May 14, 2015

+1 thanks!

lebiru commented May 14, 2015

+1 thanks!

@alesch

This comment has been minimized.

Show comment
Hide comment
@alesch

alesch May 25, 2015

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

alesch commented May 25, 2015

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

@tomByrer

This comment has been minimized.

Show comment
Hide comment
@tomByrer

tomByrer Aug 6, 2015

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

tomByrer commented Aug 6, 2015

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

@jlukic

This comment has been minimized.

Show comment
Hide comment
@jlukic

jlukic Aug 13, 2015

Using an adapted version of your luhn check in our validation
Semantic-Org/Semantic-UI@2769a6e

jlukic commented Aug 13, 2015

Using an adapted version of your luhn check in our validation
Semantic-Org/Semantic-UI@2769a6e

@liqiang372

This comment has been minimized.

Show comment
Hide comment
@liqiang372

liqiang372 Sep 9, 2015

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?

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?

@ShirtlessKirk

This comment has been minimized.

Show comment
Hide comment
@ShirtlessKirk

ShirtlessKirk Oct 27, 2015

@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.

Owner

ShirtlessKirk commented Oct 27, 2015

@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.

@thensg

This comment has been minimized.

Show comment
Hide comment
@thensg

thensg Nov 2, 2015

I decided to adapt your code, but add support for creating a Luhn checksum. You can find the changes here: https://gist.github.com/thensg/07bd82f73a1f784a35f0

thensg commented Nov 2, 2015

I decided to adapt your code, but add support for creating a Luhn checksum. You can find the changes here: https://gist.github.com/thensg/07bd82f73a1f784a35f0

@ChadReitsma

This comment has been minimized.

Show comment
Hide comment
@ChadReitsma

ChadReitsma Nov 30, 2015

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.

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.

@enapupe

This comment has been minimized.

Show comment
Hide comment
@enapupe

enapupe Dec 2, 2015

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

enapupe commented Dec 2, 2015

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

@ShirtlessKirk

This comment has been minimized.

Show comment
Hide comment
@ShirtlessKirk

ShirtlessKirk Mar 18, 2016

@enapupe: well, yeah. Credit card numbers aren't actual integers but a string of integers; every Luhn implementation expects a string to work with. Not only that, line 2 even says so...
As for returning 0, that's a falsey value, so the function still "works" ;)

Owner

ShirtlessKirk commented Mar 18, 2016

@enapupe: well, yeah. Credit card numbers aren't actual integers but a string of integers; every Luhn implementation expects a string to work with. Not only that, line 2 even says so...
As for returning 0, that's a falsey value, so the function still "works" ;)

@nani3105

This comment has been minimized.

Show comment
Hide comment
@nani3105

nani3105 Mar 22, 2016

Wow, Impressive

Wow, Impressive

@biranchi2018

This comment has been minimized.

Show comment
Hide comment
@biranchi2018

biranchi2018 Sep 21, 2016

The luhn test is failing for the MasterCard BIN 2-Series (222100-272099)

Sample Master Card:
2221 0012 3412 3456,
Expiry : 12/18

The luhn test is failing for the MasterCard BIN 2-Series (222100-272099)

Sample Master Card:
2221 0012 3412 3456,
Expiry : 12/18

@ShirtlessKirk

This comment has been minimized.

Show comment
Hide comment
@ShirtlessKirk

ShirtlessKirk Oct 11, 2016

@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...

Owner

ShirtlessKirk commented Oct 11, 2016

@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...

@heymartinadams

This comment has been minimized.

Show comment
Hide comment
@heymartinadams

heymartinadams Sep 29, 2017

Wonderful! Thank you.

heymartinadams commented Sep 29, 2017

Wonderful! Thank you.

@eugene-chernogradski

This comment has been minimized.

Show comment
Hide comment
@eugene-chernogradski

eugene-chernogradski Oct 26, 2017

@ShirtlessKirk OMFG
Phil, dude, who could've imagined it'would be your implementation of Luhn check I'm gonna use?!

eugene-chernogradski commented Oct 26, 2017

@ShirtlessKirk OMFG
Phil, dude, who could've imagined it'would be your implementation of Luhn check I'm gonna use?!

@jonbodner

This comment has been minimized.

Show comment
Hide comment
@jonbodner

jonbodner Feb 5, 2018

@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?

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment