it-swarm-ko.tech

번호에 따라 신용 카드 종류를 어떻게 감지합니까?

나는 순수하게 그 번호에 기초하여 신용 카드의 유형을 탐지하는 방법을 알아 내려고 노력하고있다. 누구든지 이것을 찾을 수있는 확실하고 신뢰할 수있는 방법을 알고 있습니까?

490
Andrew Edvalson

신용/직불 카드 번호는 PAN 또는 Primary Account Number 라고합니다. PAN의 처음 6 자리는 발행 은행에 속하는 IIN 또는 발행자 식별 번호 에서 가져옵니다. (IIN은 이전에 BIN (은행 식별 번호)으로 알려 졌으므로 일부 문서에서 해당 용어에 대한 참조를 볼 수 있습니다). 이 6 자리 숫자는 국제 표준 인 ISO/IEC 7812 를 따르며 숫자에서 카드 유형을 결정하는 데 사용할 수 있습니다.

불행히도 실제 ISO/IEC 7812 데이터베이스는 공개적으로 사용할 수 없지만 Wikipedia 를 포함하여 상업용 및 무료의 비공식 목록이 있습니다.

어쨌든 숫자에서 유형을 감지하려면 다음과 같은 정규 표현식을 사용할 수 있습니다. 원래 표현식의 크레딧

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까지의 숫자로 시작합니다. 그러나 마스터 카드 신용 카드 만 감지합니다]; 이 IIN 범위에 속하지 않는 MasterCard 시스템을 사용하여 발급 된 다른 카드가 있습니다. 2016 년에는 범위 (222100-272099)의 숫자를 추가합니다.

American Express :^3[47][0-9]{5,}$ American Express 카드 번호는 34 또는 37로 시작합니다.

Diners Club :^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Diners Club 카드 번호는 300에서 305, 36 또는 38로 시작합니다. Diners Club 카드는 5로 시작하고 16 자리입니다. Diners Club과 MasterCard의 합작 투자이며 마스터 카드처럼 처리해야합니다.

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); 가장 중요한 경우는 다른 은행의 IIN 범위에서 발행 된 Maestro 카드의 경우입니다. 결과적으로 다른 유형이 아닌 카드는 마스터 카드 여야한다고 가정하는 것이 가장 좋습니다.

중요 : 카드 번호의 길이가 다릅니다. 예를 들어, Visa는 과거에 13 자리 PAN이있는 카드와 16 자리 PAN이있는 카드를 발행했습니다. Visa의 문서는 현재 12 자리에서 19 자리 사이의 숫자를 발급했거나 발행했음을 나타냅니다. 따라서 카드 번호의 길이는 7 자리 이상인지 확인하는 것 외에는 확인하지 말아야합니다 (완전한 IIN과 하나의 확인 숫자는- The Luhn 알고리즘 ).

추가 힌트 : 카드 소지자 PAN을 처리하기 전에 공백과 문장 부호 문자를 입력에서 제거하십시오. 왜? 일반적으로 much 실제 신용 카드의 앞면에 표시되는 방식과 유사하게 그룹으로 숫자를 입력하는 것이 더 쉽기 때문에.

4444 4444 4444 4444

보다 정확하게 입력하는 것이 훨씬 쉽습니다

4444444444444444

사용자가 여기에 예상치 못한 문자를 입력했기 때문에 사용자를 쫓는 데는 아무런 이점이 없습니다.

이것은 또한 입력 필드에 적어도 24자를위한 공간이 있어야 함을 의미합니다. 그렇지 않으면 공백을 입력 한 사용자는 공간이 부족합니다. 32자를 표시하고 최대 64자를 허용 할 수 있도록 필드를 넓게 만드는 것이 좋습니다. 확장을위한 충분한 여유 공간을 제공합니다.

약간 더 통찰력을주는 이미지는 다음과 같습니다.

PDATE (2014) : 체크섬 방법 이 답변에 대한 의견에서 언급 한대로 더 이상 카드의 진위를 확인하는 유효한 방법이 아닙니다.

PDATE (2016) : 마스터 카드는 Ach Payment 로 시작하는 새로운 BIN 범위를 구현합니다.

Credit Card Verification

730
senfo

자바 스크립트에서 :

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

단위 테스트 :

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]);
            });
        });
    });
});
68
Anatoliy

2016 년 6 월 15 일 업데이트 (현재 궁극적 인 솔루션으로)

내가 투표 한도가 최고 투표로 주어 졌음에도주의하십시오. 그러나 이것들이 정규 표현식이 실제로 작동 하는지를 명확히하기 위해 수천 개의 실제 BIN 코드로 테스트했습니다. 시작 문자열 (^)을 사용하는 것이 가장 중요합니다. 그렇지 않으면 실세계에서 잘못된 결과가 나타납니다! _

JCB^(?:2131|1800|35)[0-9]{0,}$ 다음으로 시작하십시오 : 2131, 1800, 35 (3528-3589} _

아메리칸 익스프레스^3[47][0-9]{0,}$ 다음으로 시작 : 34, 37

Diners Club^3(?:0[0-59]{1}|[689])[0-9]{0,}$ 다음으로 시작 : (300-305, 309, 36, 38-39

Visa^4[0-9]{0,}$ 다음으로 시작 : 4

_ {마스터 카드^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$ 다음으로 시작 : (2221-2720, 51-55} _

Maestro^(5[06789]|6)[0-9]{0,}$ Maestro는 항상 60-69 범위에서 성장하지만, 시작하지 않거나 시작하지 않으므로 시작은 반드시 마스터 카드로 인코딩되어야합니다. 마에스트로 카드는 코드 끝 부분에서 감지해야합니다. 일부 카드는 60-69 범위에 있기 때문입니다. 코드를 살펴보십시오.

발견^(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 이벤트에 할당 할 때 유용하며 가능한 빨리 결과를 제공합니다.

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

여기에서 게임을 할 수 있습니다.

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

PHP에 대해이 함수를 사용하면 하위 VISA/MC 카드도 감지합니다. _

    /**
 * 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
}
31
Janos Szabo
  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";
    }

다음은 Regex, c #을 사용하여 신용 카드 유형을 확인하는 기능입니다.

19
Usman Younas

이것 좀 봐:

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;
}
18
Rashy

여기에 모든 CC 관련 일을위한 완전한 C # 또는 VB 코드 codeproject에 있습니다.

  • IsValidNumber
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassesLuhnTest

이 기사는 몇 년 동안 부정적인 의견이 없었습니다.

12
Simon_Weaver

최근에는 그런 기능이 필요했지만 Zend Framework 신용 카드 검사기를 루비로 포팅했습니다. Ruby gem : https://github.com/Fivell/credit_card_validations zend framework : https://github.com/zendframework/zf2/blob/master/library/Zend/Validator/CreditCard.php

그들은 둘 다 유형을 감지하기 위해 INN 범위를 사용합니다. 여기에서 INN 에 대해 읽을 수 있습니다.

이것에 따르면 신용 카드를 번갈아 검색 할 수 있지만 (정규식을 사용하지 않고 접두어와 가능한 길이에 대한 몇 가지 규칙을 선언 함)

그래서 우리는 가장 많이 사용 된 카드에 대해 다음 규칙을 가지고 있습니다.

########  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 ).

12
Fivell

PHP에서 Anatoliy의 대답 :

 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;
    }
 }
7
angelcool.net

소형 자바 스크립트 버전

    var getCardType = function (number) {
        var cards = {
            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 card in cards) {
            if (cards[card].test(number)) {
                return card;
            }
        }
    };
7
Nick

다음은 CCnumber에 의해 CCtype을 반환하는 PHP 클래스 함수입니다.
이 코드는 카드를 검증하지 않거나 실행하지 않습니다. Luhn 알고리즘은 이 페이지 의 테이블을 기반으로 신용 카드 유형을 찾습니다. 기본적으로 CC 번호 형식을 결정하기 위해 CC 번호 길이와 CC 카드 접두어를 사용합니다.

    <?php class CreditcardType
    {
   public static $creditcardTypes = array(
            array('Name'=>'American Express','cardLength'=>array(15),'cardPrefix'=>array('34', '37'))
            ,array('Name'=>'Maestro','cardLength'=>array(12, 13, 14, 15, 16, 17, 18, 19),'cardPrefix'=>array('5018', '5020', '5038', '6304', '6759', '6761', '6763'))
            ,array('Name'=>'Mastercard','cardLength'=>array(16),'cardPrefix'=>array('51', '52', '53', '54', '55'))
            ,array('Name'=>'Visa','cardLength'=>array(13,16),'cardPrefix'=>array('4'))
            ,array('Name'=>'JCB','cardLength'=>array(16),'cardPrefix'=>array('3528', '3529', '353', '354', '355', '356', '357', '358'))
            ,array('Name'=>'Discover','cardLength'=>array(16),'cardPrefix'=>array('6011', '622126', '622127', '622128', '622129', '62213',
                                        '62214', '62215', '62216', '62217', '62218', '62219',
                                        '6222', '6223', '6224', '6225', '6226', '6227', '6228',
                                        '62290', '62291', '622920', '622921', '622922', '622923',
                                        '622924', '622925', '644', '645', '646', '647', '648',
                                        '649', '65'))
            ,array('Name'=>'Solo','cardLength'=>array(16, 18, 19),'cardPrefix'=>array('6334', '6767'))
            ,array('Name'=>'Unionpay','cardLength'=>array(16, 17, 18, 19),'cardPrefix'=>array('622126', '622127', '622128', '622129', '62213', '62214',
                                        '62215', '62216', '62217', '62218', '62219', '6222', '6223',
                                        '6224', '6225', '6226', '6227', '6228', '62290', '62291',
                                        '622920', '622921', '622922', '622923', '622924', '622925'))
            ,array('Name'=>'Diners Club','cardLength'=>array(14),'cardPrefix'=>array('300', '301', '302', '303', '304', '305', '36'))
            ,array('Name'=>'Diners Club US','cardLength'=>array(16),'cardPrefix'=>array('54', '55'))
            ,array('Name'=>'Diners Club Carte Blanche','cardLength'=>array(14),'cardPrefix'=>array('300','305'))
            ,array('Name'=>'Laser','cardLength'=>array(16, 17, 18, 19),'cardPrefix'=>array('6304', '6706', '6771', '6709'))
    );     
        private function __construct() {}    
        public static function getType($CCNumber)
        {
            $CCNumber= trim($CCNumber);
            $type='Unknown';
            foreach (CreditcardType::$creditcardTypes as $card){
                if (! in_array(strlen($CCNumber),$card['cardLength'])) {
                    continue;
                }
                $prefixes = '/^('.implode('|',$card['cardPrefix']).')/';            
                if(preg_match($prefixes,$CCNumber) == 1 ){
                    $type= $card['Name'];
                    break;
                }
            }
            return $type;
        }
    } ?>
6
ismail

신용 카드의 첫 번째 숫자는 공급 업체를 추정하는 데 사용할 수 있습니다.

  • 비자 : 49,44 또는 47
  • 비자 전자 : 42, 45, 48, 49
  • 마스터 카드 : 51
  • 아멕스 : 34
  • 다이너스 : 30, 36, 38
  • JCB : 35
5
Shoban

일련의 정규식 또는 다른 하드 코딩 된 범위를 사용하는 알고리즘의 단점 인 CRR (Card Range Recognition)에서 BIN/IIN은 시간이 지남에 따라 변경됩니다. 카드의 공동 브랜딩은 진행중인 합병증입니다. 다른 카드 취득자/판매자는 동일한 카드를 다르게 취급해야 할 수도 있습니다. 지구 위치.

또한 지난 몇 년 동안 예를 들어 UnionPay 카드는 더 넓은 유통 범위에서 기존 모델은 새로운 범위에 대처하지 못하는 경우가 종종 있습니다.
일부 국가는 특정 국가에서만 사용하도록 제한되어 있으므로 시스템이 커버해야하는 지형을 알면 도움이 될 수 있습니다. 예를 들어, 범위 62는 미국에서 일부 AAA 하위 범위를 포함하지만, 판매자 기반이 미국 밖에 있으면 UnionPay로 모두 62를 취급 할 수 있습니다.
상인 위치에 따라 카드를 다르게 취급하도록 요청받을 수도 있습니다. 예 : 특정 영국 카드를 국내 계좌로 취급하지만 국제 신용으로 취급합니다.

하나의 주요 인수 은행이 유지 관리하는 매우 유용한 일련의 규칙이 있습니다. 예 : https://www.barclaycard.co.uk/business/files/BIN-Rules-EIRE.pdfhttps://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에 대한 패스 케이스가 있습니다.

5
MikeRoger

지불 처리의 일부로 신용 카드 유형을 감지하려고 시도하지 마십시오. 유효한 거래가 거부 될 위험이 있습니다.

결제 처리자에게 정보를 제공해야하는 경우 (예 : Paypal 신용 카드 객체는 카드 유형 )의 이름을 지정해야하며, 가능한 가장 적은 정보 (예 :.

$credit_card['pan'] = preg_replace('/[^0-9]/', '', $credit_card['pan']);
$inn = (int) mb_substr($credit_card['pan'], 0, 2);

// @see http://en.wikipedia.org/wiki/List_of_Bank_Identification_Numbers#Overview
if ($inn >= 40 && $inn <= 49) {
    $type = 'visa';
} else if ($inn >= 51 && $inn <= 55) {
    $type = 'mastercard';
} else if ($inn >= 60 && $inn <= 65) {
    $type = 'discover';
} else if ($inn >= 34 && $inn <= 37) {
    $type = 'amex';
} else {
    throw new \UnexpectedValueException('Unsupported card type.');
}

이 구현 (처음 두 자릿수 만 사용)은 주요 (모든 Paypal의 경우 지원되는 모든) 카드 체계를 식별하기에 충분합니다. 사실, 예외를 모두 건너 뛰고 가장 인기있는 카드 유형을 기본값으로 설정할 수 있습니다. 귀하의 요청에 응답하여 유효성 검증 오류가있는 경우 지불 게이트웨이/프로세서에 알려주십시오.

현실은 귀하의 지불 게이트웨이 귀하가 제공하는 가치에 대해 신경 쓰지 않습니다 .

5
Gajus

Swift 2.1 Usman Y의 답변 버전입니다. 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 ""

}
3
Daisy R.

내 솔루션 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이 반환되면 신용 카드 유형이 감지되지 않습니다.

"신용 카드"클래스는 신용 카드 입력 필드에 추가되어야합니다.

3
ZurabWeb

Stripe은이 환상적인 javascript library 라이브러리를 제공했습니다. 몇 가지 코드 스 니펫을 추가하고 사용법을 알려 드리겠습니다.

먼저 웹 페이지에 다음과 같이 포함 시키십시오.

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.2.3/jquery.payment.js " ></script>

두 번째로 카드 체계를 감지하기 위해 cardType 함수를 사용하십시오.

$(document).ready(function() {              
            var type = $.payment.cardType("4242 4242 4242 4242"); //test card number
            console.log(type);                                   
}); 

더 많은 예제와 데모를위한 참조 링크가 있습니다.

  1. jquery.payment.js의 스트라이프 블로그
  2. Github 저장소
2
NJInamdar

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 enum 값을 반환하는 CreditCardType.cardTypeForCreditCardNumber ( "# card number") 메서드를 호출합니다.

2
Vidyalaxmi

필자는 신용 카드 서식 및 전화 번호 서식을 꽤 많이 조사했습니다. 좋은 조언을 많이 찾았지만 실제로는 내 정확한 욕망에 맞지 않았습니다. 그래서 이 코드는 . 당신은 이것을 다음과 같이 사용합니다 :

var sf = smartForm.formatCC(myInputString);
var cardType = sf.cardType;
2
ShadeTreeDeveloper

그냥 작은 숟가락 먹이 :

$("#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");

        }

    });
1
Pinch

다음은 함수 이름에 따라 카드가 감지되면 True을 반환하는 Python으로 작성된 부울 함수의 예입니다.

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
1
radtek
// 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">&nbsp; <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
       },
1
Parvez

나는 https://github.com/bendrucker/creditcards-types/ 를 사용하여 번호에서 신용 카드 유형을 감지합니다. 내가 만난 한 가지 문제점은 테스트 번호 6011 1111 1111 1117을 발견 한 것입니다.

https://www.cybersource.com/developers/other_resources/quick_references/test_cc_numbers/ 우리는 그것이 6011부터 시작되기 때문에 발견 번호라는 것을 알 수 있습니다. 그러나 신용 카드 유형에서 얻은 결과는 다음과 같습니다. "거장". 나는이 문제를 저자에게 공개했다. 그는 곧 답변을하고이 pdf doc https://www.discovernetwork.com/downloads/IPP_VAR_Compliance.pdf 문서를 통해 우리는 6011 1111 1111 1117이 신용 카드를 발견하십시오.

0
yuxiaomin

이거 해봐. 스위프트 들어.

func checkCardValidation(number : String) -> Bool
{
    let reversedInts = number.characters.reversed().map { Int(String($0)) }
        return reversedInts.enumerated().reduce(0, {(sum, val) in
            let odd = val.offset % 2 == 1
            return sum + (odd ? (val.element! == 9 ? 9 : (val.element! * 2) % 9) : val.element!)
        }) % 10 == 0
}

용도.

if (self.checkCardValidation(number: "yourNumber") == true) {
     print("Card Number valid")
}else{
     print("Card Number not valid")
}
0
Dixit Akabari

카드 번호의 처음 6 자리 (초기 MII 자리 포함)는 발행자 식별 번호 (IIN)으로 알려져 있습니다. 이는 카드 소지자에게 카드를 발행 한 카드 발급 기관을 식별합니다. 나머지 숫자는 카드 발급 사에 의해 할당됩니다. 카드 번호의 길이는 자릿수입니다. 많은 카드 발행인이 카드에 전체 IIN 및 계좌 번호를 인쇄합니다.

위의 사실에 근거하여 나는 카드 브랜드를 식별 할 수있는 Java code의 스 니펫을 유지하고 싶습니다.

샘플 카드 유형

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

참조

0
Anoop M

해당 카드 공급 업체와 일치하는 정규 표현식 규칙 :

  • VISA의 경우 (4\d{12}(?:\d{3})?).
  • (5[1-5]\d{14}) 마스터 카드.
  • AMEX는 (3[47]\d{13})입니다.
  • Maestro에게 ((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?).
  • 다이너스 클럽의 경우 (3(?:0[0-5]|[68][0-9])[0-9]{11}).
  • Discover에 대해 (6(?:011|5[0-9]{2})[0-9]{12}).
  • (35[2-8][89]\d\d\d{10}) JCB.
0
rajan
follow Luhn’s algorithm

 private  boolean validateCreditCardNumber(String str) {

        int[] ints = new int[str.length()];
        for (int i = 0; i < str.length(); i++) {
            ints[i] = Integer.parseInt(str.substring(i, i + 1));
        }
        for (int i = ints.length - 2; i >= 0; i = i - 2) {
            int j = ints[i];
            j = j * 2;
            if (j > 9) {
                j = j % 10 + 1;
            }
            ints[i] = j;
        }
        int sum = 0;
        for (int i = 0; i < ints.length; i++) {
            sum += ints[i];
        }
        if (sum % 10 == 0) {
           return true;
        } else {
            return false;
        }


    }

then call this method

Edittext mCreditCardNumberEt;

 mCreditCardNumberEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

             int cardcount=   s.toString().length();
                 if(cardcount>=16) {
                    boolean cardnumbervalid=   validateCreditCardNumber(s.toString());
                    if(cardnumbervalid) {
                        cardvalidtesting.setText("Valid Card");
                        cardvalidtesting.setTextColor(ContextCompat.getColor(context,R.color.green));
                    }
                    else {
                        cardvalidtesting.setText("Invalid Card");
                        cardvalidtesting.setTextColor(ContextCompat.getColor(context,R.color.red));
                    }
                }
               else if(cardcount>0 &&cardcount<16) {
                     cardvalidtesting.setText("Invalid Card");
                     cardvalidtesting.setTextColor(ContextCompat.getColor(context,R.color.red));
                }

                else {
                    cardvalidtesting.setText("");

                }


                }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
0
gaurav gupta