我想知道如何仅根据信用卡的号码来判断信用卡的类型。有谁知道确定可靠的方法吗?


当前回答

Usman Y回答的Swift 2.1版本。 使用print语句来验证,因此调用某个字符串值

print(self.validateCardType(self.creditCardField.text!))

func validateCardType(testCard: String) -> String {

    let regVisa = "^4[0-9]{12}(?:[0-9]{3})?$"
    let regMaster = "^5[1-5][0-9]{14}$"
    let regExpress = "^3[47][0-9]{13}$"
    let regDiners = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"
    let regDiscover = "^6(?:011|5[0-9]{2})[0-9]{12}$"
    let regJCB = "^(?:2131|1800|35\\d{3})\\d{11}$"


    let regVisaTest = NSPredicate(format: "SELF MATCHES %@", regVisa)
    let regMasterTest = NSPredicate(format: "SELF MATCHES %@", regMaster)
    let regExpressTest = NSPredicate(format: "SELF MATCHES %@", regExpress)
    let regDinersTest = NSPredicate(format: "SELF MATCHES %@", regDiners)
    let regDiscoverTest = NSPredicate(format: "SELF MATCHES %@", regDiscover)
    let regJCBTest = NSPredicate(format: "SELF MATCHES %@", regJCB)


    if regVisaTest.evaluateWithObject(testCard){
        return "Visa"
    }
    else if regMasterTest.evaluateWithObject(testCard){
        return "MasterCard"
    }

    else if regExpressTest.evaluateWithObject(testCard){
        return "American Express"
    }

    else if regDinersTest.evaluateWithObject(testCard){
        return "Diners Club"
    }

    else if regDiscoverTest.evaluateWithObject(testCard){
        return "Discover"
    }

    else if regJCBTest.evaluateWithObject(testCard){
        return "JCB"
    }

    return ""

}

其他回答

另一个api解决方案在rapidapi银行卡位数检查有250K+发行卡类型。

只有一个GET rest api请求,并获得发卡机构信息,如:

{ "bin_number": 535177, "bank": "Finansbank A.S.", "scheme": "MASTERCARD", "type": "Debit", "country": "Turkey" }

我用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输入字段中。

一个javascript改进的@Anatoliy答案

function getCardType (number) { const numberFormated = number.replace(/\D/g, '') var patterns = { VISA: /^4[0-9]{12}(?:[0-9]{3})?$/, MASTER: /^5[1-5][0-9]{14}$/, AMEX: /^3[47][0-9]{13}$/, ELO: /^((((636368)|(438935)|(504175)|(451416)|(636297))\d{0,10})|((5067)|(4576)|(4011))\d{0,12})$/, AURA: /^(5078\d{2})(\d{2})(\d{11})$/, JCB: /^(?:2131|1800|35\d{3})\d{11}$/, DINERS: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/, DISCOVERY: /^6(?:011|5[0-9]{2})[0-9]{12}$/, HIPERCARD: /^(606282\d{10}(\d{3})?)|(3841\d{15})$/, 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+$/, } for (var key in patterns) { if (patterns[key].test(numberFormated)) { return key } } } console.log(getCardType("4539 5684 7526 2091"))

在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
  }
}

调用方法CreditCardType。cardTypeForCreditCardNumber(“#卡号”)返回CreditCardType enum值。

最近我需要这样的功能,我将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