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?
Antworten
Zu viele Anzeigen?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 .
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]);
});
});
});
});
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:
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
}
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 #
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;
}
- See previous answers
- Weitere Antworten anzeigen