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,}$ 2016年之前,万事达卡号码以数字51至55, but this will only detect MasterCard credit cards 开头;使用万事达卡系统发行的其他卡不属于此IIN范围 . 2016年,他们将增加该范围内的数字(222100-272099) .
American Express:^3[47][0-9]{5,}$ 美国运通卡号以34或37开头 .
不幸的是,万事达卡系统处理的卡类型很多,并不存在于万事达卡的IIN范围内(数字从51 ... 55开始);最重要的情况是Maestro卡,其中许多是从其他银行的IIN范围发出的,所以它们遍布数字空间 . 结果, it may be best to assume that any card that is not of some other type you accept must be a MasterCard .
Important :卡号的长度各不相同;例如,Visa过去发行了13位数的PAN卡和16位数的PAN卡 . Visa的文件目前表明它可能会发行或者可能发出12到19位数字 . Therefore, you should not check the length of the card number, other than to verify that it has at least 7 digits (对于完整的IIN加一个校验位,应该与the Luhn algorithm预测的值相匹配) .
还有一个提示: before processing a cardholder PAN, strip any whitespace and punctuation characters from the input . 为什么?因为在组中输入数字通常要容易得多,类似于它们在实际信用卡的正面显示的方式,即
4444 4444 4444 4444
比正确输入要容易得多
4444444444444444
惩罚用户真的没有任何好处,因为他们输入了你没想到的字符 .
This also implies making sure that your entry fields have room for at least 24 characters, otherwise users who enter spaces will run out of room. 我建议你让字段宽到足以显示32个字符,最多允许64个字符;这为扩展提供了充足的空间 .
这是一个提供更多洞察力的图像:
UPDATE (2014): 校验和方法 no longer appears to be a valid way of verifying a card's authenticity ,如本答案的评论中所述 .
请注意,我甚至投票支持最高投票,但为了明确这些正在实际工作的regexp我用数千个真正的BIN代码测试它 . The most important is to use start strings (^) otherwise it will give false results in real world!
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;
}
For PHP use this function, this detects some sub VISA/MC cards too:
/**
* Obtain a brand constant from a PAN
*
* @param type $pan Credit card number
* @param type $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
}
28
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";
}
我搜索了很多信用卡格式和电话号码格式 . 找到了很多很好的提示,但没有什么能真正符合我的确切需求,所以我创建了this bit of code . 你这样使用它:
var sf = smartForm.formatCC(myInputString);
var cardType = sf.cardType;
5
在swift中,您可以创建一个枚举来检测信用卡类型 .
enum CreditCardType: Int { // Enum which encapsulates different card types and method to find the type of card.
case Visa
case Master
case Amex
case Discover
func validationRegex() -> String {
var regex = ""
switch self {
case .Visa:
regex = "^4[0-9]{6,}$"
case .Master:
regex = "^5[1-5][0-9]{5,}$"
case .Amex:
regex = "^3[47][0-9]{13}$"
case .Discover:
regex = "^6(?:011|5[0-9]{2})[0-9]{12}$"
}
return regex
}
func validate(cardNumber: String) -> Bool {
let predicate = NSPredicate(format: "SELF MATCHES %@", validationRegex())
return predicate.evaluateWithObject(cardNumber)
}
// Method returns the credit card type for given card number
static func cardTypeForCreditCardNumber(cardNumber: String) -> CreditCardType? {
var creditCardType: CreditCardType?
var index = 0
while let cardType = CreditCardType(rawValue: index) {
if cardType.validate(cardNumber) {
creditCardType = cardType
break
} else {
index++
}
}
return creditCardType
}
}
// abobjects.com, parvez ahmad ab bulk mailer
use below script
function isValidCreditCard2(type, ccnum) {
if (type == "Visa") {
// Visa: length 16, prefix 4, dashes optional.
var re = /^4\d{3}?\d{4}?\d{4}?\d{4}$/;
} else if (type == "MasterCard") {
// Mastercard: length 16, prefix 51-55, dashes optional.
var re = /^5[1-5]\d{2}?\d{4}?\d{4}?\d{4}$/;
} else if (type == "Discover") {
// Discover: length 16, prefix 6011, dashes optional.
var re = /^6011?\d{4}?\d{4}?\d{4}$/;
} else if (type == "AmEx") {
// American Express: length 15, prefix 34 or 37.
var re = /^3[4,7]\d{13}$/;
} else if (type == "Diners") {
// Diners: length 14, prefix 30, 36, or 38.
var re = /^3[0,6,8]\d{12}$/;
}
if (!re.test(ccnum)) return false;
return true;
/*
// 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;
*/
}
jQuery.validator.addMethod("isValidCreditCard", function(postalcode, element) {
return isValidCreditCard2($("#cardType").val(), $("#cardNum").val());
}, "<br>credit card is invalid");
Type</td>
<td class="text"> <form:select path="cardType" cssclass="fields" style="border: 1px solid #D5D5D5;padding: 0px 0px 0px 0px;width: 130px;height: 22px;">
<option value="SELECT">SELECT</option>
<option value="MasterCard">Mastercard</option>
<option value="Visa">Visa</option>
<option value="AmEx">American Express</option>
<option value="Discover">Discover</option>
</form:select> <font color="#FF0000">*</font>
$("#signupForm").validate({
rules:{
companyName:{required: true},
address1:{required: true},
city:{required: true},
state:{required: true},
zip:{required: true},
country:{required: true},
chkAgree:{required: true},
confPassword:{required: true},
lastName:{required: true},
firstName:{required: true},
ccAddress1:{required: true},
ccZip:{
postalcode : true
},
phone:{required: true},
email:{
required: true,
email: true
},
userName:{
required: true,
minlength: 6
},
password:{
required: true,
minlength: 6
},
cardNum:{
isValidCreditCard : true
},
0
只需一点勺子喂食:
$("#CreditCardNumber").focusout(function () {
var regVisa = /^4[0-9]{12}(?:[0-9]{3})?$/;
var regMasterCard = /^5[1-5][0-9]{14}$/;
var regAmex = /^3[47][0-9]{13}$/;
var regDiscover = /^6(?:011|5[0-9]{2})[0-9]{12}$/;
if (regVisa.test($(this).val())) {
$("#CCImage").html("<img height='40px' src='@Url.Content("~/images/visa.png")'>");
}
else if (regMasterCard.test($(this).val())) {
$("#CCImage").html("<img height='40px' src='@Url.Content("~/images/mastercard.png")'>");
}
else if (regAmex.test($(this).val())) {
$("#CCImage").html("<img height='40px' src='@Url.Content("~/images/amex.png")'>");
}
else if (regDiscover.test($(this).val())) {
$("#CCImage").html("<img height='40px' src='@Url.Content("~/images/discover.png")'>");
}
else {
$("#CCImage").html("NA");
}
});
0
下面是一些用Python编写的布尔函数的示例,如果根据函数名检测到卡,则返回 True .
def is_american_express(cc_number):
"""Checks if the card is an american express. If us billing address country code, & is_amex, use vpos
https://en.wikipedia.org/wiki/Bank_card_number#cite_note-GenCardFeatures-3
:param cc_number: unicode card number
"""
return bool(re.match(r'^3[47][0-9]{13}$', cc_number))
def is_visa(cc_number):
"""Checks if the card is a visa, begins with 4 and 12 or 15 additional digits.
:param cc_number: unicode card number
"""
# Standard Visa is 13 or 16, debit can be 19
if bool(re.match(r'^4', cc_number)) and len(cc_number) in [13, 16, 19]:
return True
return False
def is_mastercard(cc_number):
"""Checks if the card is a mastercard. Begins with 51-55 or 2221-2720 and 16 in length.
:param cc_number: unicode card number
"""
if len(cc_number) == 16 and cc_number.isdigit(): # Check digit, before cast to int
return bool(re.match(r'^5[1-5]', cc_number)) or int(cc_number[:4]) in range(2221, 2721)
return False
def is_discover(cc_number):
"""Checks if the card is discover, re would be too hard to maintain. Not a supported card.
:param cc_number: unicode card number
"""
if len(cc_number) == 16:
try:
# return bool(cc_number[:4] == '6011' or cc_number[:2] == '65' or cc_number[:6] in range(622126, 622926))
return bool(cc_number[:4] == '6011' or cc_number[:2] == '65' or 622126 <= int(cc_number[:6]) <= 622925)
except ValueError:
return False
return False
def is_jcb(cc_number):
"""Checks if the card is a jcb. Not a supported card.
:param cc_number: unicode card number
"""
# return bool(re.match(r'^(?:2131|1800|35\d{3})\d{11}$', cc_number)) # wikipedia
return bool(re.match(r'^35(2[89]|[3-8][0-9])[0-9]{12}$', cc_number)) # PawelDecowski
def is_diners_club(cc_number):
"""Checks if the card is a diners club. Not a supported card.
:param cc_number: unicode card number
"""
return bool(re.match(r'^3(?:0[0-6]|[68][0-9])[0-9]{11}$', cc_number)) # 0-5 = carte blance, 6 = international
def is_laser(cc_number):
"""Checks if the card is laser. Not a supported card.
:param cc_number: unicode card number
"""
return bool(re.match(r'^(6304|670[69]|6771)', cc_number))
def is_maestro(cc_number):
"""Checks if the card is maestro. Not a supported card.
:param cc_number: unicode card number
"""
possible_lengths = [12, 13, 14, 15, 16, 17, 18, 19]
return bool(re.match(r'^(50|5[6-9]|6[0-9])', cc_number)) and len(cc_number) in possible_lengths
# Child cards
def is_visa_electron(cc_number):
"""Child of visa. Checks if the card is a visa electron. Not a supported card.
:param cc_number: unicode card number
"""
return bool(re.match(r'^(4026|417500|4508|4844|491(3|7))', cc_number)) and len(cc_number) == 16
def is_total_rewards_visa(cc_number):
"""Child of visa. Checks if the card is a Total Rewards Visa. Not a supported card.
:param cc_number: unicode card number
"""
return bool(re.match(r'^41277777[0-9]{8}$', cc_number))
def is_diners_club_carte_blanche(cc_number):
"""Child card of diners. Checks if the card is a diners club carte blance. Not a supported card.
:param cc_number: unicode card number
"""
return bool(re.match(r'^30[0-5][0-9]{11}$', cc_number)) # github PawelDecowski, jquery-creditcardvalidator
def is_diners_club_carte_international(cc_number):
"""Child card of diners. Checks if the card is a diners club international. Not a supported card.
:param cc_number: unicode card number
"""
return bool(re.match(r'^36[0-9]{12}$', cc_number)) # jquery-creditcardvalidator
public static final String AMERICAN_EXPRESS = "American Express";
public static final String DISCOVER = "Discover";
public static final String JCB = "JCB";
public static final String DINERS_CLUB = "Diners Club";
public static final String VISA = "Visa";
public static final String MASTERCARD = "MasterCard";
public static final String UNKNOWN = "Unknown";
卡前缀
// Based on http://en.wikipedia.org/wiki/Bank_card_number#Issuer_identification_number_.28IIN.29
public static final String[] PREFIXES_AMERICAN_EXPRESS = {"34", "37"};
public static final String[] PREFIXES_DISCOVER = {"60", "62", "64", "65"};
public static final String[] PREFIXES_JCB = {"35"};
public static final String[] PREFIXES_DINERS_CLUB = {"300", "301", "302", "303", "304", "305", "309", "36", "38", "39"};
public static final String[] PREFIXES_VISA = {"4"};
public static final String[] PREFIXES_MASTERCARD = {
"2221", "2222", "2223", "2224", "2225", "2226", "2227", "2228", "2229",
"223", "224", "225", "226", "227", "228", "229",
"23", "24", "25", "26",
"270", "271", "2720",
"50", "51", "52", "53", "54", "55"
};
检查输入的数字是否具有任何给定的前缀 .
public String getBrand(String number) {
String evaluatedType;
if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_AMERICAN_EXPRESS)) {
evaluatedType = AMERICAN_EXPRESS;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_DISCOVER)) {
evaluatedType = DISCOVER;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_JCB)) {
evaluatedType = JCB;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_DINERS_CLUB)) {
evaluatedType = DINERS_CLUB;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_VISA)) {
evaluatedType = VISA;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_MASTERCARD)) {
evaluatedType = MASTERCARD;
} else {
evaluatedType = UNKNOWN;
}
return evaluatedType;
}
最后,效用方法
/**
* Check to see if the input number has any of the given prefixes.
*
* @param number the number to test
* @param prefixes the prefixes to test against
* @return {@code true} if number begins with any of the input prefixes
*/
public static boolean hasAnyPrefix(String number, String... prefixes) {
if (number == null) {
return false;
}
for (String prefix : prefixes) {
if (number.startsWith(prefix)) {
return true;
}
}
return false;
}
26 回答
信用卡/借记卡号码称为 PAN 或主帐号 . PAN的前六位数字取自属于发行银行的 IIN 或发行人识别号码(IIN以前称为BIN - 银行识别号码 - 因此您可能会在某些文档中看到对该术语的引用) . 这六位数符合国际标准ISO/IEC 7812,可用于从号码中确定卡的类型 .
遗憾的是,实际的ISO / IEC 7812数据库尚未公开,但有非官方列表,包括商业和免费,包括on Wikipedia .
无论如何,要从数字中检测类型,您可以使用如下所示的正则表达式:Credit for original expressions
Visa:
^4[0-9]{6,}$
Visa卡号码以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,}$
2016年之前,万事达卡号码以数字51至55, but this will only detect MasterCard credit cards 开头;使用万事达卡系统发行的其他卡不属于此IIN范围 . 2016年,他们将增加该范围内的数字(222100-272099) .American Express:
^3[47][0-9]{5,}$
美国运通卡号以34或37开头 .Diners Club:
^3(?:0[0-5]|[68][0-9])[0-9]{4,}$
大莱卡号码以300至305,36或38开头 . 大莱卡的卡片以5开头,有16位数字 . 这些是大莱卡和万事达卡之间的合资企业,应该像万事达卡一样处理 .Discover:
^6(?:011|5[0-9]{2})[0-9]{3,}$
发现卡号以6011或65开头 .JCB:
^(?:2131|1800|35[0-9]{3})[0-9]{3,}$
JCB卡以2131,1800或35开头 .不幸的是,万事达卡系统处理的卡类型很多,并不存在于万事达卡的IIN范围内(数字从51 ... 55开始);最重要的情况是Maestro卡,其中许多是从其他银行的IIN范围发出的,所以它们遍布数字空间 . 结果, it may be best to assume that any card that is not of some other type you accept must be a MasterCard .
Important :卡号的长度各不相同;例如,Visa过去发行了13位数的PAN卡和16位数的PAN卡 . Visa的文件目前表明它可能会发行或者可能发出12到19位数字 . Therefore, you should not check the length of the card number, other than to verify that it has at least 7 digits (对于完整的IIN加一个校验位,应该与the Luhn algorithm预测的值相匹配) .
还有一个提示: before processing a cardholder PAN, strip any whitespace and punctuation characters from the input . 为什么?因为在组中输入数字通常要容易得多,类似于它们在实际信用卡的正面显示的方式,即
比正确输入要容易得多
惩罚用户真的没有任何好处,因为他们输入了你没想到的字符 .
This also implies making sure that your entry fields have room for at least 24 characters, otherwise users who enter spaces will run out of room. 我建议你让字段宽到足以显示32个字符,最多允许64个字符;这为扩展提供了充足的空间 .
这是一个提供更多洞察力的图像:
UPDATE (2014): 校验和方法 no longer appears to be a valid way of verifying a card's authenticity ,如本答案的评论中所述 .
UPDATE (2016): 万事达卡是从Ach Payment开始实现新的BIN范围 .
在javascript中:
单元测试:
Updated: 15th June 2016 (目前作为最终解决方案)
请注意,我甚至投票支持最高投票,但为了明确这些正在实际工作的regexp我用数千个真正的BIN代码测试它 . The most important is to use start strings (^) otherwise it will give false results in real world!
JCB
^(?:2131|1800|35)[0-9]{0,}$
开头: 2131, 1800, 35 (3528-3589)American Express
^3[47][0-9]{0,}$
开头: 34, 37Diners Club
^3(?:0[0-59]{1}|[689])[0-9]{0,}$
开头: 300-305, 309, 36, 38-39Visa
^4[0-9]{0,}$
开头: 4MasterCard
^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$
开头: 2221-2720, 51-55Maestro
^(5[06789]|6)[0-9]{0,}$
Maestro总是在范围内增长: 60-69 ,以/不是别的开头,但是起始5必须编码为万事达卡 . 必须在代码末尾检测到Maestro卡,因为其他一些卡的范围为60-69 . 请看代码 .Discover
^(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在 javascript 我使用此功能 . 当你将它分配给onkeyup事件并且它尽快给出结果时,这很好 .
在这里你可以玩它:
http://jsfiddle.net/upN3L/69/
For PHP use this function, this detects some sub VISA/MC cards too:
以下是使用Regex检查信用卡类型的功能,c#
看一下这个:
http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CC70060A01B
这是关于codeproject的Complete C# or VB code for all kinds of CC related things .
IsValidNumber
GetCardTypeFromNumber
GetCardTestNumber
PassesLuhnTest
这篇文章已经有几年了,没有负面评论 .
最近我需要这样的功能,我正在将Zend Framework信用卡验证器移植到ruby . ruby gem:https://github.com/Fivell/credit_card_validations zend framework:https://github.com/zendframework/zf2/blob/master/library/Zend/Validator/CreditCard.php
他们都使用INN范围来检测类型 . 在这里你可以阅读about INN
根据这个你可以检测信用卡(没有正则表达式,但声明一些关于前缀和可能的长度的规则)
所以我们有下一个规则对于大多数使用的卡
然后通过搜索前缀和比较长度,您可以检测信用卡品牌 . 另外不要忘记luhn algoritm(在这里描述http://en.wikipedia.org/wiki/Luhn) .
紧凑的JavaScript版本
Anatoliy在PHP中的答案:
这是一个php类函数,由CCnumber返回CCtype .
此代码不验证卡或不运行Luhn算法只尝试根据this page中的表查找信用卡类型 . 基本上使用CCnumber长度和CCcard前缀来确定CCcard类型 .
不要尝试在处理付款时检测信用卡类型 . 您有可能拒绝有效的交易 .
如果您需要向付款处理商提供信息(例如,PayPal信用卡对象需要命名card type),请根据可用的最少信息进行猜测,例如:
这种实现(仅使用前两位数字)足以识别所有主要(在PayPal的情况下所有支持的)卡方案 . 实际上,您可能希望完全跳过该异常并默认为最常用的卡类型 . 让支付网关/处理器告诉您是否存在响应您的请求的验证错误 .
现实是您的支付网关does not care about the value you provide .
信用卡的第一个数字可用于估算供应商:
签证:49,44或47
签证电子:42,45,48,49
万事达卡:51
美国运通:34
食客:30,36,38
JCB:35
在卡片范围识别(CRR)中,使用一系列正则表达式或其他硬编码范围的算法的缺点是BIN / IIN在我的经验中确实会随着时间的推移而发生变化 . 卡片的联合品牌是一个持续的复杂因素 . 不同的卡片购买者/商家可能需要以不同的方式对待同一张卡片,具体取决于例如地理位置 .
另外,在过去几年中,例如银联卡在更广泛的流通中,现有的型号无法应对新的范围,有时会与它们取代的更广泛的范围交错 .
了解您的系统需要覆盖的地理位置可能有所帮助,因为某些范围仅限于在特定国家/地区使用 . 例如,范围62包括美国的一些AAA子范围,但如果您的商家基地位于美国境外,您可以将所有62个视为银联 .
您可能还会被要求根据商家位置对卡进行不同的处理 . 例如 . 将某些英国卡片视为国内借记卡,但作为国际信用卡 .
一个主要的收购银行维护着非常有用的规则 . 例如 . https://www.barclaycard.co.uk/business/files/BIN-Rules-EIRE.pdf和https://www.barclaycard.co.uk/business/files/BIN-Rules-UK.pdf . (截至2017年6月的有效链接,这要归功于提供更新参考链接的用户 . )但请注意,虽然这些CRR规则可能代表发卡领域,因为它适用于该实体获得的商家,它不包括例如标识为CUP / UPI的范围 .
这些注释适用于磁条(MagStripe)或PKE(Pan Key Entry)场景 . ICC / EMV世界的情况再次不同 .
更新:此页面上的其他答案(以及链接的WikiPedia页面)JCB始终为16长 . 然而,在我的公司,我们有一个专门的工程师团队,他们在多个收单银行和地区认证我们的POS设备和软件 . 这支团队最近从JCB获得的认证证书包含19个长PAN的通行证 .
我的jQuery解决方案:
如果返回0,则不会检测到信用卡类型 .
应将“creditcard”类添加到信用卡输入字段中 .
Swift 2.1版本的Usman Y的回答 . 使用print语句通过某个字符串值来验证调用
Stripe为卡方案检测提供了这个出色的 javascript 库 . 让我添加一些代码片段,并向您展示如何使用它 .
首先将其包含在您的网页中
其次使用函数cardType来检测卡方案 .
以下是更多示例和演示的参考链接 .
Stripe blog for jquery.payment.js
Github repository
我搜索了很多信用卡格式和电话号码格式 . 找到了很多很好的提示,但没有什么能真正符合我的确切需求,所以我创建了this bit of code . 你这样使用它:
在swift中,您可以创建一个枚举来检测信用卡类型 .
调用CreditCardType.cardTypeForCreditCardNumber(“#card number”)方法,该方法返回CreditCardType枚举值 .
只需一点勺子喂食:
下面是一些用Python编写的布尔函数的示例,如果根据函数名检测到卡,则返回
True
.与respective card vendors匹配的正则表达式规则:
签证
(4\d{12}(?:\d{3})?)
.(5[1-5]\d{14})
适用于万事达卡 .AMEX的
(3[47]\d{13})
.((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?)
为Maestro .009
(3(?:0[0-5]|[68][0-9])[0-9]{11})
适合大来俱乐部 .(6(?:011|5[0-9]{2})[0-9]{12})
for Discover .(35[2-8][89]\d\d\d{10})
代表JCB .基于以上事实,我想保留一段 JAVA 代码来识别卡牌 .
Reference
我使用https://github.com/bendrucker/creditcards-types/从号码中检测信用卡类型 . 我遇到的一个问题是发现测试号6011 1111 1111 1117
从https://www.cybersource.com/developers/other_resources/quick_references/test_cc_numbers/我们可以看到它是一个发现号,因为它从6011开始 . 但我从信用卡类型得到的结果是"Maestro" . 我向作者公开了这个问题 . 他很快回复了我并提供了这个pdf文档https://www.discovernetwork.com/downloads/IPP_VAR_Compliance.pdf从文档我们可以清楚地看到6011 1111 1111 1117不属于发现信用卡的范围 .
试试吧 . 快点 .
使用 .