On Jan 14, 3:29 am, Jack Killpatrick <j...@ihwy.com> wrote: > Hi All, > > We've released a new version of our jQuery Validation plugin credit card > extension.
It is likely that such validation is more hassle than it's worth... > Changes include: > > 1. updated card prefixes (including latest Discover Card changes) > 2. support for LaserCard ...because you have to keep upadting the data and possibly the algorithms and the data object structure if it turns out it isn't suitable - perhaps cards have different rules depending on the prefix or number of characters, the plugin data structure can't handle that. If this is intended for an online payment system, it is more effective to just give the data to the payment system and let it work it out. Otherwise you are potentially preventing users from accessing the payment system even though their details are valid and you can't be sure that you've prevented invalid data being sent - so what do you really gain? The code itself seems a bit verbose and has redunant checks, e.g. value = value.replace(/[\s-]/g, ""); // remove spaces and dashes if (value.length == 0) { return false; } // no length /* RG This test is redundant. If the cardNumber has fewer than the required number of digits it will fail the test below. */ var cardNo = value; /* RG value has already beem modified from the value passed, there doesn't seem much point in protecting its value now. */ var cardexp = /^[0-9]{13,19}$/; if (!cardexp.exec(cardNo)) { return false; } // has chars or wrong length cardNo = cardNo.replace(/\D/g, ""); // strip down to digits /* RG cardNo has already had spaces removed and been checked to ensure that it contains only digits. What is left to remove? Also, the two tests use different (though likely practically identical) patterns: [0-9] vs \D. */ The code implementing the Mod 10 algorithm is inefficient and verbose, some comments: var checksum = 0; var mychar = ""; mychar is not used. var j = 1; var calc; for (i = cardNo.length - 1; i >= 0; i--) { calc = Number(cardNo.charAt(i)) * j; There is no need for the call to Number(), multiplication will convert the string to a number anyway. if (calc > 9) { checksum = checksum + 1; calc = calc - 10; } checksum = checksum + calc; All of that can be replaced with: checksum += (calc > 9)? calc - 9 : calc; The line: if (j == 1) { j = 2 } else { j = 1 }; That can be: j = (j%2) + 1; } if (checksum % 10 != 0) { return false; } // not mod10 Consider: return !(checksum%10); or perhaps: return /0$/.test(checksum); If the function is called frequently, the regExp can be stored in a closure - whatever suits. An alternative Mod 10 implementation is: var acc = cardNo.split(''); var i = acc.length; var j = 0; var n; var sum = 0; while (i--) { n = (j++ % 2)? acc[i] * 2 : acc[i]; sum += (n < 10)? n - 0 : n - 9; } return !(sum%10); The prefix and length checks can also be done in less code (4 or 5 lines) and more efficiently using regular expressions. -- Rob