Credit Card Validator

This code snippet analyzes the given card number and checks, if it is valid and not just random. Thanks to David Walsh who wrote the base. http://davidwalsh.name/validate-credit-cards I improved his code with the Luhn algorithm.

by Leonardo Trimarchi

HTML

<h1>Credit Card Validator</h1>
<form>
    <p>Please select a card trader and enter a credit card number.</p>
    <label for="card">Card trader</label>
    <select id="card">
        <option value="" disabled="disabled">Card trader...</option>
        <option value="mc" selected="selected">Master Card</option>
        <option value="ec">Electronic Cash</option>
        <option value="vi">Visa Card</option>
        <option value="ax">American Express</option>
        <option value="dc">DC</option>
        <option value="bl">BL</option>
        <option value="di">Diner's Club</option>
        <option value="jcb">JCB</option>
        <option value="er">ER</option>
    </select>
    <br />
    <label for="number">Card number</label>
    <input type="text" id="number" value="5100 - 0000 - 0000 - 0040" />
    <br />
    <button type="submit">Validate Card</button>
</form>

CSS

html {
    background: #202020 url(http://i.imgur.com/oQXkL.jpg) center center;
    color: #EEE;
    font-size: 1em;
}
body {
    padding: 10px;
    margin: 50px;
    border: 2px solid #EEE;
    border-radius: 10px;
    box-shadow: 0 0 17px -2px #FEE;
    background: #504040;
}
h1 {
    font-size: 2em;
}

label {
    width: 100px;
    margin-right: 10px;
    display: inline-block;
}
select, input {
    width: 200px;
    display: inline-block;
}

.success {
    text-shadow: 0 0 5px #CFC;
}
.failed {
    text-shadow: 0 0 5px #FCC;
}

JavaScript

// Create an object
var creditCardValidator = {
    // Pin the cards to them
    'cards': {
        'mc':    '5[1-5][0-9]{14}',
        'ec':    '5[1-5][0-9]{14}',
        'vi':    '4(?:[0-9]{12}|[0-9]{15})',
        'ax':    '3[47][0-9]{13}',
        'dc':    '3(?:0[0-5][0-9]{11}|[68][0-9]{12})',
        'bl':    '3(?:0[0-5][0-9]{11}|[68][0-9]{12})',
        'di':    '6011[0-9]{12}',
        'jcb':    '(?:3[0-9]{15}|(2131|1800)[0-9]{11})',
        'er':    '2(?:014|149)[0-9]{11}'
    },
    // Add the structure validator to them
    'validateStructure': function(value, ccType) {
        value = String(value).replace(/[^0-9]/g, ''); // ignore dashes and whitespaces - We could even ignore all non-numeric chars (/[^0-9]/g)

        var cardinfo = creditCardValidator.cards,
            results  = [];
        if(ccType){
            var expr = '^' + cardinfo[ccType.toLowerCase()] + '$';
            return expr ? !!value.match(expr) : false; // boolean
        }

        for(var i in cardinfo){
            if(value.match('^' + cardinfo[i] + '$')){
                results.push(i);
            }
        }
        return results.length ? results.join('|') : false; // String | boolean
    },
    // Add the Luhn validator to them
    'validateChecksum': function(value) {
        value = String(value).replace(/[^0-9]/g, ''); // ignore dashes and whitespaces - We could even ignore all non-numeric chars (/[^0-9]/g)
        
        var sum        = 0,
            parity    = value.length % 2;
        
        for(var i = 0; i <= (value.length - 1); i++) { // We'll iterate LTR - it's faster and needs less calculating
            var digit = parseInt(value[i], 10);
            
            if(i % 2 == parity) {
                digit = digit * 2;
            }
            if(digit > 9) {
                digit = digit - 9; // get the cossfoot - Exp: 10 - 9 = 1 + 0 | 12 - 9 = 1 + 2 | ... | 18 - 9 = 1 + 8
            }
            
            sum += digit;
        }
        
     ...