10

We all know that 42 is the answer to everything, but it's news to me that it is a valid credit card number.

Try entering '42' or '42176' into this jQuery Validation testing page and click OK.

What's going on? I thought this was supposed to be the de-facto validation library. Even Microsoft is using it now, but it thinks '42' and '42176' are valid credit card numbers?! It's not even doing a length check. Surely I'm not responsible for adding a length check too? It's called 'creditcard' validator and not 'luhn' validator.

Edit: hitchhiker humor aside - how would I go about patching the validation plugin to check length. is that easy?

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689

4 Answers4

12

This is probably because this validator merely checks that the number supplied satisfies the LUHN-10 algorithm (which 42 satisfies since 4*2 + 2 = 10 which is 0 modulo 10).

A better validator should maybe check for a minimal number of digits.

I'm not sure this corresponds to the very latest code from jQuery, but I found the snippet associated with credit card validation:

    // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
    // based on http://en.wikipedia.org/wiki/Luhn
    creditcard: function(value, element) {
        if ( this.optional(element) )
            return "dependency-mismatch";
        // accept only digits and dashes
        if (/[^0-9-]+/.test(value))
            return false;
        var nCheck = 0,
            nDigit = 0,
            bEven = false;

        value = value.replace(/\D/g, "");

        for (n = value.length - 1; n >= 0; n--) {
            var cDigit = value.charAt(n);
            var nDigit = parseInt(cDigit, 10);
            if (bEven) {
                if ((nDigit *= 2) > 9)
                    nDigit -= 9;
            }
            nCheck += nDigit;
            bEven = !bEven;
        }

        return (nCheck % 10) == 0;
    },

... and as you see this merely check that all characters are digits and that LUHN-10 is satisfied, without any attention to a minial length.

mjv
  • 73,152
  • 14
  • 113
  • 156
8

You can combine the credit card rule with the minimum and maximum length rules to achieve what you want. That may seem like too much effort -- and I might agree -- though it does give you more control if you only want to accept certain card number lengths.

$('form').validate({
    '#ccNum': {
                   creditcard: true,
                   required: true,
                   minlength: 13,
                   maxlength: 19
              }
});
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
6

The length of credit card numbers can vary depending on the issuer (though yes, there's generally a minimum length of ~13 digits). However, since this is client-side validation, the focus is probably more on reducing the chance of a small typo, and less on checking arbitrary data. That should probably be done server-side.

Amber
  • 507,862
  • 82
  • 626
  • 550
  • but the problem is if you've already got it wrong once - as you begin to start typing to correct it it will tell you *as youre typing* that its correct, and then wrong, and then correct again. all credit cards must be at least 15 characters right - so why isnt it making a check. i have the source i suppose but it just makes me weary of using this library overall. – Simon_Weaver Dec 08 '09 at 02:37
  • The length must be between 13 and 19 digits, in general. – dave4420 Dec 08 '09 at 02:39
  • 1
    The 19-digit max is a limitation of ISO 7812. Theoretically a card number might be as few as 6 digits (for the IIN), though in practice 13-digit cards are the shortest that have been commonly issued by the financial industry (and they are no longer in use). – bobince Dec 08 '09 at 03:15
0

I have corrected the jQuery validate function to consider credit card length in validation.

I added the following to the credit card validation code-

if (value.length > 19 || value.length<12)
{
    return (false);
}

The complete code for the creditcard validation part is as follows:-

creditcard: function(value, element) {
if ( this.optional(element) )
return "dependency-mismatch";
// accept only digits and dashes
if (/[^0-9-]+/.test(value))
return false;

// Modified part to check minimum and maximum card length
if (value.length > 19 || value.length<12)
{
    return (false);
}

var nCheck = 0,
nDigit = 0,
bEven = false;
value = value.replace(/\D/g, "");

for (n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n);
var nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9)
nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}

return (nCheck % 10) == 0;
},

I have hard coded the minimum and maximum card lengths as 12 and 19 respectively.

Sparky
  • 4,769
  • 8
  • 37
  • 52