Credit Card Verifier

Card Number Syntax Validation Script

Credit Card Verifier validates credit card number syntax using the Luhn algorithm (MOD10 check). It verifies Visa, MasterCard, Discover, and American Express card numbers to catch typos and invalid numbers before processing.

Free Download
Version 1.0
Perl CGI

Overview

Credit Card Verifier was written by Spider and validates credit card numbers using the Luhn algorithm (also known as the MOD10 check). This mathematical formula catches most common typos and random number entries before they're submitted to payment processors.

What the Luhn Algorithm Does

The Luhn algorithm is a checksum formula used to validate identification numbers like credit card numbers. It catches single-digit errors and most transpositions. A syntactically valid card number doesn't mean the card is real or has funds - it just means the number follows the correct format.

Supported Card Types
Card Type Prefix Length
Visa 4 13 or 16 digits
MasterCard 51-55, 2221-2720 16 digits
American Express 34, 37 15 digits
Discover 6011, 644-649, 65 16 digits
Security Notice
  • Never store full card numbers
  • Don't log card numbers
  • Use HTTPS always
  • Not PCI compliant alone
  • Use proper payment gateways

Package Contents

File Description
cc_ver.pl Main Perl script that performs the credit card validation
cc_form.html Sample HTML form for collecting and validating card numbers
readme.txt Installation instructions and configuration guide

Installation

  1. Upload the Script
    Upload cc_ver.pl to your cgi-bin directory over a secure connection.
  2. Configure Perl Path
    Edit the first line to point to your Perl interpreter (usually #!/usr/bin/perl).
  3. Set Permissions
    Set the script permissions to 755: chmod 755 cc_ver.pl
  4. Upload Form
    Upload cc_form.html or integrate validation into your existing checkout form.
  5. Enable HTTPS
    Ensure your site uses HTTPS for any page handling card numbers.

Code Examples

Perl - Luhn Algorithm Implementation
#!/usr/bin/perl
use strict;
use warnings;

# Luhn algorithm (MOD10 check)
sub validate_card_number {
    my ($number) = @_;

    # Remove spaces and dashes
    $number =~ s/[\s\-]//g;

    # Check if only digits
    return 0 unless $number =~ /^\d+$/;

    my $sum = 0;
    my $alt = 0;

    # Process digits from right to left
    for my $digit (reverse split //, $number) {
        if ($alt) {
            $digit *= 2;
            $digit -= 9 if $digit > 9;
        }
        $sum += $digit;
        $alt = !$alt;
    }

    return ($sum % 10) == 0;
}

# Identify card type
sub identify_card_type {
    my ($number) = @_;
    $number =~ s/[\s\-]//g;

    return 'American Express' if $number =~ /^3[47]\d{13}$/;
    return 'Visa' if $number =~ /^4\d{12}(\d{3})?$/;
    return 'MasterCard' if $number =~ /^(5[1-5]\d{14}|2(2[2-9][1-9]|[3-6]\d{2}|7[01]\d|720)\d{12})$/;
    return 'Discover' if $number =~ /^(6011|64[4-9]|65)\d{12,15}$/;
    return 'Unknown';
}

# Example usage
my $card = '4111111111111111';  # Test Visa number

if (validate_card_number($card)) {
    my $type = identify_card_type($card);
    print "Valid $type card number\n";
} else {
    print "Invalid card number\n";
}
PHP - Luhn Algorithm Implementation
<?php
/**
 * Credit Card Verifier - PHP Version
 */

function validateCardNumber($number) {
    // Remove spaces and dashes
    $number = preg_replace('/[\s\-]/', '', $number);

    // Check if only digits
    if (!ctype_digit($number)) {
        return false;
    }

    $sum = 0;
    $length = strlen($number);
    $parity = $length % 2;

    for ($i = 0; $i < $length; $i++) {
        $digit = (int)$number[$i];

        if ($i % 2 == $parity) {
            $digit *= 2;
            if ($digit > 9) {
                $digit -= 9;
            }
        }

        $sum += $digit;
    }

    return ($sum % 10) === 0;
}

function identifyCardType($number) {
    $number = preg_replace('/[\s\-]/', '', $number);

    $patterns = [
        'American Express' => '/^3[47]\d{13}$/',
        'Visa' => '/^4\d{12}(\d{3})?$/',
        'MasterCard' => '/^(5[1-5]\d{14}|2(2[2-9][1-9]|[3-6]\d{2}|7[01]\d|720)\d{12})$/',
        'Discover' => '/^(6011|64[4-9]|65)\d{12,15}$/',
    ];

    foreach ($patterns as $type => $pattern) {
        if (preg_match($pattern, $number)) {
            return $type;
        }
    }

    return 'Unknown';
}

// Example usage
$card = '4111111111111111';  // Test Visa number

if (validateCardNumber($card)) {
    $type = identifyCardType($card);
    echo "Valid $type card number";
} else {
    echo "Invalid card number";
}
?>
JavaScript - Client-Side Validation (Recommended)
/**
 * Credit Card Verifier - JavaScript Version
 * Client-side validation for immediate feedback
 */

class CreditCardValidator {
    // Luhn algorithm (MOD10 check)
    static validateNumber(number) {
        // Remove spaces and dashes
        number = number.replace(/[\s\-]/g, '');

        // Check if only digits
        if (!/^\d+$/.test(number)) {
            return false;
        }

        let sum = 0;
        let alternate = false;

        // Process digits from right to left
        for (let i = number.length - 1; i >= 0; i--) {
            let digit = parseInt(number[i], 10);

            if (alternate) {
                digit *= 2;
                if (digit > 9) {
                    digit -= 9;
                }
            }

            sum += digit;
            alternate = !alternate;
        }

        return (sum % 10) === 0;
    }

    // Identify card type
    static identifyType(number) {
        number = number.replace(/[\s\-]/g, '');

        const patterns = {
            'American Express': /^3[47]\d{13}$/,
            'Visa': /^4\d{12}(\d{3})?$/,
            'MasterCard': /^(5[1-5]\d{14}|2(2[2-9][1-9]|[3-6]\d{2}|7[01]\d|720)\d{12})$/,
            'Discover': /^(6011|64[4-9]|65)\d{12,15}$/,
            'Diners Club': /^3(0[0-5]|[68]\d)\d{11}$/,
            'JCB': /^35(2[89]|[3-8]\d)\d{12}$/,
        };

        for (const [type, pattern] of Object.entries(patterns)) {
            if (pattern.test(number)) {
                return type;
            }
        }

        return 'Unknown';
    }

    // Format card number with spaces
    static formatNumber(number) {
        number = number.replace(/\D/g, '');
        const type = this.identifyType(number);

        if (type === 'American Express') {
            // AMEX: 4-6-5
            return number.replace(/(\d{4})(\d{6})(\d{5})/, '$1 $2 $3').trim();
        } else {
            // Others: 4-4-4-4
            return number.replace(/(\d{4})(?=\d)/g, '$1 ').trim();
        }
    }

    // Get card icon class
    static getCardIcon(type) {
        const icons = {
            'Visa': 'bi-credit-card-2-front',
            'MasterCard': 'bi-credit-card-2-back',
            'American Express': 'bi-credit-card',
            'Discover': 'bi-credit-card-fill',
        };
        return icons[type] || 'bi-credit-card';
    }
}

// Real-time validation example
document.getElementById('card-number')?.addEventListener('input', function(e) {
    const number = e.target.value;
    const isValid = CreditCardValidator.validateNumber(number);
    const type = CreditCardValidator.identifyType(number);

    // Update UI
    const feedback = document.getElementById('card-feedback');
    if (number.length >= 13) {
        feedback.textContent = isValid
            ? `Valid ${type} card`
            : 'Invalid card number';
        feedback.className = isValid ? 'text-success' : 'text-danger';
    }

    // Format as user types
    if (e.inputType !== 'deleteContentBackward') {
        e.target.value = CreditCardValidator.formatNumber(number);
    }
});

// Test numbers (for development only!)
const testCards = {
    visa: '4111111111111111',
    mastercard: '5555555555554444',
    amex: '378282246310005',
    discover: '6011111111111117',
};

Download

Compressed Archives
  • ccver.tar.gz 6.2 KB
  • ccver.zip 6.6 KB
  • ccver.tar.Z 9.3 KB
  • ccver.tar 30.7 KB
Individual Files
  • cc_ver.pl

    Main Perl script for credit card validation

  • cc_form.html

    Sample HTML form for card input

  • readme.txt

    Installation and configuration guide

Frequently Asked Questions

The original script only validates card number syntax. To validate expiry dates, add a check that the month is 01-12 and the expiry date is in the future. However, a "valid" expiry date only means it's properly formatted and not past - actual validation requires a payment gateway.

No, this script only validates the card number syntax. It cannot verify that a card is real, active, has available credit, or belongs to the person using it. For actual payment processing, you must use a payment gateway like Stripe, PayPal, or your merchant bank's API.

The Luhn algorithm (also called MOD10) is a checksum formula developed by Hans Peter Luhn in 1954. It's used to validate credit card numbers, IMEI numbers, and other identification numbers. It works by doubling every second digit from the right, summing all digits, and checking if the result is divisible by 10.

No. PCI compliance requires much more than syntax validation. If you handle credit card data, you must follow PCI DSS requirements including encryption, access controls, network security, and regular audits. For most businesses, the easiest path is using a payment gateway that handles card data so you never touch it.

Only if you're PCI compliant. For most businesses, you should NEVER store full credit card numbers. Use a payment gateway that provides tokens or customer IDs instead. If you must store card data, encrypt it properly, limit access, and undergo regular PCI audits.

Use both. Client-side JavaScript validation provides immediate feedback and improves user experience. Server-side validation (never trust client data) catches invalid numbers before processing. Modern payment widgets from Stripe, Braintree, etc. handle this automatically.

For payment processing, use established services like Stripe, PayPal, Square, or Braintree. They provide JavaScript widgets that handle validation, formatting, and security. Your server never sees raw card numbers, which simplifies PCI compliance significantly.

Payment gateways provide test card numbers. Common ones include: Visa: 4111111111111111, MasterCard: 5555555555554444, Amex: 378282246310005, Discover: 6011111111111117. These pass Luhn validation but will fail real payment processing. Check your gateway's documentation for their specific test numbers.