600 Stimmen

Wie kann man den Kreditkartentyp anhand der Nummer erkennen?

Ich versuche herauszufinden, wie ich die Art der Kreditkarte allein anhand ihrer Nummer erkennen kann. Kennt jemand eine eindeutige, zuverlässige Methode, um dies herauszufinden?

893voto

senfo Punkte 27580

Die Kredit-/Debitkartennummer wird als PAN ou Primäre Kontonummer . Die ersten sechs Ziffern der PAN werden aus dem IIN ou Emittenten-Identifikationsnummer (IINs waren früher unter der Bezeichnung BIN - Bank Identification Numbers - bekannt, so dass in einigen Dokumenten auf diese Terminologie Bezug genommen wird). Diese sechs Ziffern unterliegen einem internationalen Standard, ISO/IEC 7812 und kann anhand der Nummer die Art der Karte bestimmen.

Leider ist die eigentliche ISO/IEC 7812-Datenbank nicht öffentlich zugänglich, aber es gibt inoffizielle Listen, sowohl kommerzielle als auch freie, darunter auf Wikipedia .

Um den Typ anhand der Nummer zu ermitteln, können Sie einen regulären Ausdruck wie den folgenden verwenden: Anerkennung von Originalausdrücken

Visum: ^4[0-9]{6,}$ Visa-Kartennummern beginnen mit einer 4.

MasterCard: ^5[1-5][0-9]{5,}|222[1-9][0-9]{3,}|22[3-9][0-9]{4,}|2[3-6][0-9]{5,}|27[01][0-9]{4,}|2720[0-9]{3,}$ Vor 2016 beginnen die MasterCard-Nummern mit den Ziffern 51 bis 55, allerdings werden damit nur MasterCard-Kreditkarten erkannt Es gibt andere Karten, die über das MasterCard-System ausgegeben werden und nicht in diesen IIN-Bereich fallen. Im Jahr 2016 werden sie Nummern im Bereich (222100-272099) hinzufügen.

American Express: ^3[47][0-9]{5,}$ American Express Kartennummern beginnen mit 34 oder 37.

Diners Club: ^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Diners Club-Kartennummern beginnen mit 300 bis 305, 36 oder 38. Es gibt Diners Club Karten, die mit 5 beginnen und 16 Ziffern haben. Diese sind ein Joint Venture zwischen Diners Club und MasterCard und sollten wie eine MasterCard behandelt werden.

Entdecken: ^6(?:011|5[0-9]{2})[0-9]{3,}$ Discover-Kartennummern beginnen mit 6011 oder 65.

JCB: ^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ JCB-Karten beginnen mit 2131, 1800 oder 35.

Leider gibt es eine Reihe von Kartentypen, die über das MasterCard-System abgewickelt werden und nicht im IIN-Bereich von MasterCard (Nummern ab 51...55) angesiedelt sind; der wichtigste Fall sind die Maestro-Karten, von denen viele aus den IIN-Bereichen anderer Banken herausgegeben wurden und sich daher im gesamten Nummernraum befinden. Daraus folgt, Am besten ist es, wenn Sie davon ausgehen, dass jede Karte, die Sie nicht von einem anderen Typ akzeptieren, eine MasterCard sein muss. .

Wichtig : Die Kartennummern variieren in ihrer Länge; so hat Visa in der Vergangenheit Karten mit 13-stelligen PANs und Karten mit 16-stelligen PANs ausgegeben. Aus den Unterlagen von Visa geht hervor, dass das Unternehmen derzeit Nummern mit 12 bis 19 Ziffern ausgeben kann oder ausgegeben hat. Daher sollten Sie die Länge der Kartennummer nicht überprüfen, sondern nur sicherstellen, dass sie mindestens 7 Ziffern hat. (für eine vollständige IIN plus eine Prüfziffer, die mit dem Wert übereinstimmen sollte, der durch der Luhn-Algorithmus ).

Ein weiterer Hinweis: vor der Verarbeitung einer Karteninhaber-PAN alle Leer- und Interpunktionszeichen aus der Eingabe entfernen . Warum? Weil es typisch ist viel Es ist einfacher, die Ziffern in Gruppen einzugeben, ähnlich wie sie auf der Vorderseite einer echten Kreditkarte angezeigt werden, d. h.

4444 4444 4444 4444

ist viel einfacher richtig einzugeben als

4444444444444444

Es hat wirklich keinen Sinn, den Benutzer zu tadeln, weil er Zeichen eingegeben hat, die man hier nicht erwartet.

Dies bedeutet auch, dass Sie sicherstellen müssen, dass Ihre Eingabefelder Platz haben für au moins 24 Zeichen, da sonst bei der Eingabe von Leerzeichen kein Platz mehr ist. Ich würde empfehlen, das Feld so breit zu machen, dass 32 Zeichen angezeigt werden können, und bis zu 64 Zeichen zuzulassen; das lässt viel Spielraum für Erweiterungen.

Hier ist ein Bild, das etwas mehr Aufschluss gibt:

UPDATE (2016): Mastercard führt ab sofort neue BIN-Bereiche ein Ach Zahlung .

Credit Card Verification

97voto

Anatoliy Punkte 28289

In Javascript:

function detectCardType(number) {
    var re = {
        electron: /^(4026|417500|4405|4508|4844|4913|4917)\d+$/,
        maestro: /^(5018|5020|5038|5612|5893|6304|6759|6761|6762|6763|0604|6390)\d+$/,
        dankort: /^(5019)\d+$/,
        interpayment: /^(636)\d+$/,
        unionpay: /^(62|88)\d+$/,
        visa: /^4[0-9]{12}(?:[0-9]{3})?$/,
        mastercard: /^5[1-5][0-9]{14}$/,
        amex: /^3[47][0-9]{13}$/,
        diners: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
        discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
        jcb: /^(?:2131|1800|35\d{3})\d{11}$/
    }

    for(var key in re) {
        if(re[key].test(number)) {
            return key
        }
    }
}

Einheitstest:

describe('CreditCard', function() {
    describe('#detectCardType', function() {

        var cards = {
            '8800000000000000': 'UNIONPAY',

            '4026000000000000': 'ELECTRON',
            '4175000000000000': 'ELECTRON',
            '4405000000000000': 'ELECTRON',
            '4508000000000000': 'ELECTRON',
            '4844000000000000': 'ELECTRON',
            '4913000000000000': 'ELECTRON',
            '4917000000000000': 'ELECTRON',

            '5019000000000000': 'DANKORT',

            '5018000000000000': 'MAESTRO',
            '5020000000000000': 'MAESTRO',
            '5038000000000000': 'MAESTRO',
            '5612000000000000': 'MAESTRO',
            '5893000000000000': 'MAESTRO',
            '6304000000000000': 'MAESTRO',
            '6759000000000000': 'MAESTRO',
            '6761000000000000': 'MAESTRO',
            '6762000000000000': 'MAESTRO',
            '6763000000000000': 'MAESTRO',
            '0604000000000000': 'MAESTRO',
            '6390000000000000': 'MAESTRO',

            '3528000000000000': 'JCB',
            '3589000000000000': 'JCB',
            '3529000000000000': 'JCB',

            '6360000000000000': 'INTERPAYMENT',

            '4916338506082832': 'VISA',
            '4556015886206505': 'VISA',
            '4539048040151731': 'VISA',
            '4024007198964305': 'VISA',
            '4716175187624512': 'VISA',

            '5280934283171080': 'MASTERCARD',
            '5456060454627409': 'MASTERCARD',
            '5331113404316994': 'MASTERCARD',
            '5259474113320034': 'MASTERCARD',
            '5442179619690834': 'MASTERCARD',

            '6011894492395579': 'DISCOVER',
            '6011388644154687': 'DISCOVER',
            '6011880085013612': 'DISCOVER',
            '6011652795433988': 'DISCOVER',
            '6011375973328347': 'DISCOVER',

            '345936346788903': 'AMEX',
            '377669501013152': 'AMEX',
            '373083634595479': 'AMEX',
            '370710819865268': 'AMEX',
            '371095063560404': 'AMEX'
        };

        Object.keys(cards).forEach(function(number) {
            it('should detect card ' + number + ' as ' + cards[number], function() {
                Basket.detectCardType(number).should.equal(cards[number]);
            });
        });
    });
});

57voto

Janos Szabo Punkte 1246

Aktualisiert: 15. Juni 2016 (als derzeit ultimative Lösung)

Bitte beachten Sie, dass ich sogar geben Stimme für die eine ist top abgestimmt, aber um es klar, diese sind die regexps tatsächlich funktioniert ich es mit Tausenden von echten BIN-Codes getestet. Das Wichtigste ist die Verwendung von Startzeichenketten (^), da sonst in der realen Welt falsche Ergebnisse erzielt werden!

JCB ^(?:2131|1800|35)[0-9]{0,}$ Beginnen Sie mit: 2131, 1800, 35 (3528-3589)

American Express ^3[47][0-9]{0,}$ Beginnen Sie mit: 34, 37

Diners Club ^3(?:0[0-59]{1}|[689])[0-9]{0,}$ Beginnen Sie mit: 300-305, 309, 36, 38-39

Visum ^4[0-9]{0,}$ Beginnen Sie mit: 4

MasterCard ^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$ Beginnen Sie mit: 2221-2720, 51-55

Maestro ^(5[06789]|6)[0-9]{0,}$ Maestro wächst immer weiter in der Reichweite: 60-69 , angefangen mit / nicht etwas anderes, aber ab 5 muss sowieso als Mastercard verschlüsselt werden. Maestro-Karten müssen am Ende des Codes erkannt werden, weil einige andere im Bereich von 60-69 hat. Bitte schauen Sie sich den Code an.

Entdecken Sie ^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$ Entdecken Sie ziemlich schwierig zu codieren, beginnen Sie mit: 6011, 622126-622925, 644-649, 65

Sur javascript Ich verwende diese Funktion. Dies ist gut, wenn u weisen Sie es auf ein onkeyup-Ereignis und es geben Ergebnis so schnell wie möglich.

function cc_brand_id(cur_val) {
    // the regular expressions check for possible matches as you type, hence the OR operators based on the number of chars
    // regexp string length {0} provided for soonest detection of beginning of the card numbers this way it could be used for BIN CODE detection also

    //JCB
    jcb_regex = new RegExp('^(?:2131|1800|35)[0-9]{0,}$'); //2131, 1800, 35 (3528-3589)
    // American Express
    amex_regex = new RegExp('^3[47][0-9]{0,}$'); //34, 37
    // Diners Club
    diners_regex = new RegExp('^3(?:0[0-59]{1}|[689])[0-9]{0,}$'); //300-305, 309, 36, 38-39
    // Visa
    visa_regex = new RegExp('^4[0-9]{0,}$'); //4
    // MasterCard
    mastercard_regex = new RegExp('^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$'); //2221-2720, 51-55
    maestro_regex = new RegExp('^(5[06789]|6)[0-9]{0,}$'); //always growing in the range: 60-69, started with / not something else, but starting 5 must be encoded as mastercard anyway
    //Discover
    discover_regex = new RegExp('^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$');
    ////6011, 622126-622925, 644-649, 65

    // get rid of anything but numbers
    cur_val = cur_val.replace(/\D/g, '');

    // checks per each, as their could be multiple hits
    //fix: ordering matter in detection, otherwise can give false results in rare cases
    var sel_brand = "unknown";
    if (cur_val.match(jcb_regex)) {
        sel_brand = "jcb";
    } else if (cur_val.match(amex_regex)) {
        sel_brand = "amex";
    } else if (cur_val.match(diners_regex)) {
        sel_brand = "diners_club";
    } else if (cur_val.match(visa_regex)) {
        sel_brand = "visa";
    } else if (cur_val.match(mastercard_regex)) {
        sel_brand = "mastercard";
    } else if (cur_val.match(discover_regex)) {
        sel_brand = "discover";
    } else if (cur_val.match(maestro_regex)) {
        if (cur_val[0] == '5') { //started 5 must be mastercard
            sel_brand = "mastercard";
        } else {
            sel_brand = "maestro"; //maestro is all 60-69 which is not something else, thats why this condition in the end
        }
    }

    return sel_brand;
}

Hier können Sie damit spielen:

http://jsfiddle.net/upN3L/69/

Für PHP verwenden Sie diese Funktion, die auch einige Sub-VISA/MC-Karten erkennt:

/**
  * Obtain a brand constant from a PAN
  *
  * @param string $pan               Credit card number
  * @param bool   $include_sub_types Include detection of sub visa brands
  * @return string
  */
public static function getCardBrand($pan, $include_sub_types = false)
{
    //maximum length is not fixed now, there are growing number of CCs has more numbers in length, limiting can give false negatives atm

    //these regexps accept not whole cc numbers too
    //visa
    $visa_regex = "/^4[0-9]{0,}$/";
    $vpreca_regex = "/^428485[0-9]{0,}$/";
    $postepay_regex = "/^(402360|402361|403035|417631|529948){0,}$/";
    $cartasi_regex = "/^(432917|432930|453998)[0-9]{0,}$/";
    $entropay_regex = "/^(406742|410162|431380|459061|533844|522093)[0-9]{0,}$/";
    $o2money_regex = "/^(422793|475743)[0-9]{0,}$/";

    // MasterCard
    $mastercard_regex = "/^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$/";
    $maestro_regex = "/^(5[06789]|6)[0-9]{0,}$/";
    $kukuruza_regex = "/^525477[0-9]{0,}$/";
    $yunacard_regex = "/^541275[0-9]{0,}$/";

    // American Express
    $amex_regex = "/^3[47][0-9]{0,}$/";

    // Diners Club
    $diners_regex = "/^3(?:0[0-59]{1}|[689])[0-9]{0,}$/";

    //Discover
    $discover_regex = "/^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$/";

    //JCB
    $jcb_regex = "/^(?:2131|1800|35)[0-9]{0,}$/";

    //ordering matter in detection, otherwise can give false results in rare cases
    if (preg_match($jcb_regex, $pan)) {
        return "jcb";
    }

    if (preg_match($amex_regex, $pan)) {
        return "amex";
    }

    if (preg_match($diners_regex, $pan)) {
        return "diners_club";
    }

    //sub visa/mastercard cards
    if ($include_sub_types) {
        if (preg_match($vpreca_regex, $pan)) {
            return "v-preca";
        }
        if (preg_match($postepay_regex, $pan)) {
            return "postepay";
        }
        if (preg_match($cartasi_regex, $pan)) {
            return "cartasi";
        }
        if (preg_match($entropay_regex, $pan)) {
            return "entropay";
        }
        if (preg_match($o2money_regex, $pan)) {
            return "o2money";
        }
        if (preg_match($kukuruza_regex, $pan)) {
            return "kukuruza";
        }
        if (preg_match($yunacard_regex, $pan)) {
            return "yunacard";
        }
    }

    if (preg_match($visa_regex, $pan)) {
        return "visa";
    }

    if (preg_match($mastercard_regex, $pan)) {
        return "mastercard";
    }

    if (preg_match($discover_regex, $pan)) {
        return "discover";
    }

    if (preg_match($maestro_regex, $pan)) {
        if ($pan[0] == '5') { //started 5 must be mastercard
            return "mastercard";
        }
        return "maestro"; //maestro is all 60-69 which is not something else, thats why this condition in the end

    }

    return "unknown"; //unknown for this system
}

26voto

Usman Younas Punkte 1273
public string GetCreditCardType(string CreditCardNumber)
{
    Regex regVisa = new Regex("^4[0-9]{12}(?:[0-9]{3})?$");
    Regex regMaster = new Regex("^5[1-5][0-9]{14}$");
    Regex regExpress = new Regex("^3[47][0-9]{13}$");
    Regex regDiners = new Regex("^3(?:0[0-5]|[68][0-9])[0-9]{11}$");
    Regex regDiscover = new Regex("^6(?:011|5[0-9]{2})[0-9]{12}$");
    Regex regJCB = new Regex("^(?:2131|1800|35\\d{3})\\d{11}$");

    if (regVisa.IsMatch(CreditCardNumber))
        return "VISA";
    else if (regMaster.IsMatch(CreditCardNumber))
        return "MASTER";
    else  if (regExpress.IsMatch(CreditCardNumber))
        return "AEXPRESS";
    else if (regDiners.IsMatch(CreditCardNumber))
        return "DINERS";
    else if (regDiscover.IsMatch(CreditCardNumber))
        return "DISCOVERS";
    else if (regJCB.IsMatch(CreditCardNumber))
        return "JCB";
    else
        return "invalid";
}

Hier ist die Funktion zu überprüfen Kreditkarte Typ mit Regex, c #

21voto

Rashy Punkte 863

Sehen Sie sich das an:

http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CC70060A01B

function isValidCreditCard(type, ccnum) {
    /* Visa: length 16, prefix 4, dashes optional.
    Mastercard: length 16, prefix 51-55, dashes optional.
    Discover: length 16, prefix 6011, dashes optional.
    American Express: length 15, prefix 34 or 37.
    Diners: length 14, prefix 30, 36, or 38. */

    var re = new Regex({
        "visa": "/^4\d{3}-?\d{4}-?\d{4}-?\d",
        "mc": "/^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/",
        "disc": "/^6011-?\d{4}-?\d{4}-?\d{4}$/",
        "amex": "/^3[47]\d{13}$/",
        "diners": "/^3[068]\d{12}$/"
    }[type.toLowerCase()])

    if (!re.test(ccnum)) return false;
    // Remove all dashes for the checksum checks to eliminate negative numbers
    ccnum = ccnum.split("-").join("");
    // Checksum ("Mod 10")
    // Add even digits in even length strings or odd digits in odd length strings.
    var checksum = 0;
    for (var i = (2 - (ccnum.length % 2)); i <= ccnum.length; i += 2) {
        checksum += parseInt(ccnum.charAt(i - 1));
    }
    // Analyze odd digits in even length strings or even digits in odd length strings.
    for (var i = (ccnum.length % 2) + 1; i < ccnum.length; i += 2) {
        var digit = parseInt(ccnum.charAt(i - 1)) * 2;
        if (digit < 10) { checksum += digit; } else { checksum += (digit - 9); }
    }
    if ((checksum % 10) == 0) return true;
    else return false;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X