The Holy Java

Building the right thing, building it right, fast

How To Generate A Valid Credit Card Number For A Bin (First 6 Digits)

Posted by Jakub Holý on March 25, 2014

There is plenty of generators that can produce numbers that are valid credit card numbers according to the Luhn check and specific rules of the individual issuer companies. However I have not found anything that would generate the missing digits given a bin, i.e. the first 6 digits of a credit card (the “bank identification number”). So I created one, reverse-engineering org.apache.commons.validator.routines.CreditCardValidator from common-validator 1.4:

// Groovy:
/** Map RegExp from C.C.Validator to the total length of the CC# */
binReToLen = [
        (~/^(3[47]\d{0,13})$/) : 13+2, // amex
        (~/^30[0-5]\d{0,11}$/) : 11+3, // diners 1
        (~/^(3095\d{0,10})$/) : 10+4, // diners 2
        (~/^(36\d{0,12})$/) : 12+2,     // diners 3
        (~/^|3[8-9]\d{0,12}$/) : 12+2,  // diners 4
        (~/^(5[1-5]\d{0,14})$/) : 14+2, // master
        (~/^(4)(\d{0,12}|\d{15})$/) : 12+1 // visa
        // Discover cards omitted
]

/** Bin is e.g. 123456 */
def completeCCn(String bin) {
    def ccnFill = "1" * 19
    int ccnLen = lenForBin(bin)

    def ccnWithoutCheck = bin + ccnFill[0..<(ccnLen - 6 - 1)] // - bin, - check digit

    def check = computeLuhncheckDigit(ccnWithoutCheck)

    return "$ccnWithoutCheck$check"
}

def lenForBin(String bin) {
    def match = binReToLen.find { it.key.matcher(bin).matches() }
    if (match == null) {
        throw new RuntimeException("Bin $bin does not match any known CC issuer")
    }
    match.value
}

def computeLuhncheckDigit(def ccnWithoutCheck) {
    org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit.LUHN_CHECK_DIGIT.calculate(ccnWithoutCheck)
}

completeCCn('465944') // => 4659441111118

Testing FTW!

Advertisements

Sorry, the comment form is closed at this time.

 
%d bloggers like this: