我想知道如何仅根据信用卡的号码来判断信用卡的类型。有谁知道确定可靠的方法吗?
当前回答
斯威夫特 5+
extension String {
func isMatch(_ Regex: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: Regex)
let results = regex.matches(in: self, range: NSRange(self.startIndex..., in: self))
return results.map {
String(self[Range($0.range, in: self)!])
}.count > 0
} catch {
return false
}
}
func getCreditCardType() -> String? {
let VISA_Regex = "^4[0-9]{6,}$"
let MasterCard_Regex = "^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,}$"
let AmericanExpress_Regex = "^3[47][0-9]{5,}$"
let DinersClub_Regex = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"
let Discover_Regex = "^6(?:011|5[0-9]{2})[0-9]{3,}$"
let JCB_Regex = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"
if self.isMatch(VISA_Regex) {
return "VISA"
} else if self.isMatch(MasterCard_Regex) {
return "MasterCard"
} else if self.isMatch(AmericanExpress_Regex) {
return "AmericanExpress"
} else if self.isMatch(DinersClub_Regex) {
return "DinersClub"
} else if self.isMatch(Discover_Regex) {
return "Discover"
} else if self.isMatch(JCB_Regex) {
return "JCB"
} else {
return nil
}
}
}
使用。
"1234123412341234".getCreditCardType()
其他回答
我用jQuery的解决方案:
function detectCreditCardType() {
var type = new Array;
type[1] = '^4[0-9]{12}(?:[0-9]{3})?$'; // visa
type[2] = '^5[1-5][0-9]{14}$'; // mastercard
type[3] = '^6(?:011|5[0-9]{2})[0-9]{12}$'; // discover
type[4] = '^3[47][0-9]{13}$'; // amex
var ccnum = $('.creditcard').val().replace(/[^\d.]/g, '');
var returntype = 0;
$.each(type, function(idx, re) {
var regex = new RegExp(re);
if(regex.test(ccnum) && idx>0) {
returntype = idx;
}
});
return returntype;
}
如果返回0,则未检测到信用卡类型。
“creditcard”类应该添加到creditcard输入字段中。
最近我需要这样的功能,我将Zend框架信用卡验证器移植到ruby。 红宝石宝石:https://github.com/Fivell/credit_card_validations zend框架:https://github.com/zendframework/zf2/blob/master/library/Zend/Validator/CreditCard.php
它们都使用INN范围来检测类型。在这里你可以读到关于INN的信息
根据这一点,您可以选择检测信用卡(没有regexp,但声明一些关于前缀和可能长度的规则)
所以我们有关于最常用卡片的下一个规则
######## most used brands #########
visa: [
{length: [13, 16], prefixes: ['4']}
],
mastercard: [
{length: [16], prefixes: ['51', '52', '53', '54', '55']}
],
amex: [
{length: [15], prefixes: ['34', '37']}
],
######## other brands ########
diners: [
{length: [14], prefixes: ['300', '301', '302', '303', '304', '305', '36', '38']},
],
#There are Diners Club (North America) cards that begin with 5. These are a joint venture between Diners Club and MasterCard, and are processed like a MasterCard
# will be removed in next major version
diners_us: [
{length: [16], prefixes: ['54', '55']}
],
discover: [
{length: [16], prefixes: ['6011', '644', '645', '646', '647', '648',
'649', '65']}
],
jcb: [
{length: [16], prefixes: ['3528', '3529', '353', '354', '355', '356', '357', '358', '1800', '2131']}
],
laser: [
{length: [16, 17, 18, 19], prefixes: ['6304', '6706', '6771']}
],
solo: [
{length: [16, 18, 19], prefixes: ['6334', '6767']}
],
switch: [
{length: [16, 18, 19], prefixes: ['633110', '633312', '633304', '633303', '633301', '633300']}
],
maestro: [
{length: [12, 13, 14, 15, 16, 17, 18, 19], prefixes: ['5010', '5011', '5012', '5013', '5014', '5015', '5016', '5017', '5018',
'502', '503', '504', '505', '506', '507', '508',
'6012', '6013', '6014', '6015', '6016', '6017', '6018', '6019',
'602', '603', '604', '605', '6060',
'677', '675', '674', '673', '672', '671', '670',
'6760', '6761', '6762', '6763', '6764', '6765', '6766', '6768', '6769']}
],
# Luhn validation are skipped for union pay cards because they have unknown generation algoritm
unionpay: [
{length: [16, 17, 18, 19], prefixes: ['622', '624', '625', '626', '628'], skip_luhn: true}
],
dankrot: [
{length: [16], prefixes: ['5019']}
],
rupay: [
{length: [16], prefixes: ['6061', '6062', '6063', '6064', '6065', '6066', '6067', '6068', '6069', '607', '608'], skip_luhn: true}
]
}
然后通过搜索前缀和比较长度来检测信用卡品牌。也不要忘记luhn算法(在http://en.wikipedia.org/wiki/Luhn有描述)。
更新
更新的规则列表可以在这里找到https://raw.githubusercontent.com/Fivell/credit_card_validations/master/lib/data/brands.yaml
这里有完整的c#或VB代码,用于各种CC相关的东西。
IsValidNumber GetCardTypeFromNumber GetCardTestNumber PassesLuhnTest
这篇文章已经发布了几年,没有任何负面评论。
斯威夫特 5+
extension String {
func isMatch(_ Regex: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: Regex)
let results = regex.matches(in: self, range: NSRange(self.startIndex..., in: self))
return results.map {
String(self[Range($0.range, in: self)!])
}.count > 0
} catch {
return false
}
}
func getCreditCardType() -> String? {
let VISA_Regex = "^4[0-9]{6,}$"
let MasterCard_Regex = "^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,}$"
let AmericanExpress_Regex = "^3[47][0-9]{5,}$"
let DinersClub_Regex = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"
let Discover_Regex = "^6(?:011|5[0-9]{2})[0-9]{3,}$"
let JCB_Regex = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"
if self.isMatch(VISA_Regex) {
return "VISA"
} else if self.isMatch(MasterCard_Regex) {
return "MasterCard"
} else if self.isMatch(AmericanExpress_Regex) {
return "AmericanExpress"
} else if self.isMatch(DinersClub_Regex) {
return "DinersClub"
} else if self.isMatch(Discover_Regex) {
return "Discover"
} else if self.isMatch(JCB_Regex) {
return "JCB"
} else {
return nil
}
}
}
使用。
"1234123412341234".getCreditCardType()
anatoly用PHP回答:
public static function detectCardType($num)
{
$re = array(
"visa" => "/^4[0-9]{12}(?:[0-9]{3})?$/",
"mastercard" => "/^5[1-5][0-9]{14}$/",
"amex" => "/^3[47][0-9]{13}$/",
"discover" => "/^6(?:011|5[0-9]{2})[0-9]{12}$/",
);
if (preg_match($re['visa'],$num))
{
return 'visa';
}
else if (preg_match($re['mastercard'],$num))
{
return 'mastercard';
}
else if (preg_match($re['amex'],$num))
{
return 'amex';
}
else if (preg_match($re['discover'],$num))
{
return 'discover';
}
else
{
return false;
}
}