Kredi kartı türünü numaraya göre nasıl tespit edersiniz?


516

Ben tamamen kendi sayısına göre kredi kartı türünü tespit etmek nasıl anlamaya çalışıyorum. Bunu bulmak için kesin ve güvenilir bir yol bilen var mı?


3
Normal bir ifade kullanma. Daha fazla bilgi için bu bağlantıya göz atın .
senfo

3
Tüm detaylar Wikipedia'da mevcut: en.wikipedia.org/wiki/Credit_card_numbers
Sten Vesterli

1
Wikipedia'da en.wikipedia.org/wiki/Credit_card_numbers adresinde iyi bir özet tablosu var . Kartın türünü ve yayıncısını söyleyen ilk altı basamaklı sayıdır.
Alex

3
İlk sayısal grubu çıkarmak dışında bir normal ifade kullanmazdım, genellikle ilk 4 sayıdan (ABD'de) anlayabilirsiniz. Ayrıca bir ödemeyi silmek için ödeme yapmadan önce, meşru olabileceğinden emin olmak için kart numarasında bir Mod 10 sağlama toplamı çalıştırın. Luhn algoritması
Dan Blair

3
ayrıca herkes bu algoritmaların 'tüm zamanlar için' iyi olup olmadığını yorumlayabilir veya periyodik olarak değişebilir mi, örneğin 'bir telefon numarasının Kaliforniya'da olup olmadığını hesaplama' algoritması gibi
Simon_Weaver

Yanıtlar:


772

Kredi / banka kartı numarasına PAN veya Ana Hesap Numarası denir . PAN'ın ilk altı basamağı , ihraç eden bankaya ait IIN veya İhraççı Kimlik Numarasından alınır (IIN'ler daha önce BIN - Banka Kimlik Numaraları olarak biliniyordu - bu nedenle bazı belgelerde bu terminolojiye referanslar görebilirsiniz). Bu altı hane uluslararası bir standart olan ISO / IEC 7812'ye tabidir ve numaradan kart türünü belirlemek için kullanılabilir.

Ne yazık ki, gerçek ISO / IEC 7812 veritabanı herkese açık değildir, ancak Wikipedia da dahil olmak üzere hem ticari hem de ücretsiz resmi olmayan listeler vardır .

Her neyse, sayıdan türü algılamak için aşağıdaki gibi normal bir ifade kullanabilirsiniz: Orijinal ifadeler için kredi

Visa: ^4[0-9]{6,}$ Visa kart numaraları 4 ile başlar.

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'dan önce MasterCard numaraları 51 ile 55 arasındaki rakamlarla başlar, ancak bu yalnızca MasterCard kredi kartlarını algılar ; MasterCard sistemi kullanılarak verilen ve bu IIN aralığına girmeyen diğer kartlar da vardır. 2016 yılında aralığa numara ekleyeceklerdir (222100-272099).

American Express: ^3[47][0-9]{5,}$ American Express kart numaraları 34 veya 37 ile başlar.

Diners Club: ^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Diners Club kart numaraları 300 - 305, 36 veya 38 ile başlar. 5 ile başlayan ve 16 basamaklı Diners Club kartları vardır. Bunlar Diners Club ve MasterCard arasındaki ortak girişimdir ve MasterCard gibi işlenmelidir.

Discover: ^6(?:011|5[0-9]{2})[0-9]{3,}$ Discover kart numaraları 6011 veya 65 ile başlar.

JCB: ^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ JCB kartları 2131, 1800 veya 35 ile başlar.

Ne yazık ki, MasterCard sistemi ile işlenen ve MasterCard'ın IIN aralığında (sayı 51 ... 55'ten başlayan rakamlar) bulunmayan bir dizi kart türü vardır; en önemli durum, çoğu diğer bankaların IIN serilerinden ihraç edilen ve bu nedenle sayı alanının her yerinde bulunan Maestro kartlarının durumudur. Sonuç olarak, kabul ettiğiniz başka türden olmayan kartların MasterCard olması gerektiğini varsaymak en iyisi olabilir .

Önemli : kart numaralarının uzunluğu değişir; örneğin, Visa geçmişte 13 haneli PAN'lı kartlar ve 16 haneli PAN'lı kartlar vermiştir. Visa'nın belgeleri şu anda 12 ila 19 basamaklı sayıları yayınlayabileceğini veya vermiş olabileceğini göstermektedir. Bu nedenle, kart numarasının uzunluğunu, en az 7 hane olduğunu doğrulamak dışında kontrol etmemelisiniz (tam bir IIN artı bir Luhn algoritması tarafından öngörülen değerle eşleşmesi gereken bir kontrol basamağı için ).

Bir ipucu daha: bir kart sahibi PAN işlemeden önce, boşluk ve noktalama karakterlerini girişten ayırın . Neden? Çünkü rakamları, gerçek bir kredi kartının ön yüzünde nasıl göründüklerine benzer şekilde gruplara girmek genellikle daha kolaydır.

4444 4444 4444 4444

doğru girmek çok daha kolay

4444444444444444

Burada beklemediğiniz karakterleri girdikleri için kullanıcıyı azarlamanın hiçbir yararı yoktur.

Bu aynı zamanda giriş alanlarınızın en az 24 karaktere sahip olduğundan emin olmanız anlamına gelir , aksi takdirde boşluklara giren kullanıcılar odadan çıkar. Alanı 32 karakter görüntüleyecek ve 64 karaktere kadar izin verebilecek kadar geniş yapmanızı öneririm; genişleme için bol miktarda boşluk sağlar.

İşte size biraz daha fazla bilgi veren bir resim:

GÜNCELLEME (2014): Sağlama toplamı yöntemi , bu yanıtın yorumlarında belirtildiği gibi bir kartın orijinalliğini doğrulamanın geçerli bir yolu gibi görünmüyor .

GÜNCELLEME (2016): Mastercard, Ach Payment'den başlayarak yeni BIN aralıklarını uygulayacak .

kredi kartı onayı


7
harika bir örnek. maestro kartları için düzenli ifadeniz var mı?
Manikandan

4
Hayır hayır hayır. Kart numaralarının uzunluğuna güvenemezsiniz; istedikleri zaman değişebilirler. Güvenebileceğiniz kart numarasının tek kısmı IIN'dir (eskiden BIN olarak bilinirdi) ve bu numaranın bir önekidir. Ayrıca, olamaz önerdiğiniz şekilde Mastercard kartlarını tespit; yalnızca Mastercard sistemi ile işlenen kartların bir alt kümesini alır (asıl sorun çeşitli IIN öneklerine sahip Maestro kartlarıdır).
alastair

2
@alastair Yorum yapmadan önce ifadeleri okudunuz mu? IIN'yi kullanmak için özel olarak yazıldılar, bu yüzden ne söylemeye çalıştığınızı anlamıyorum. Ayrıca IIN, kart düzenleyicisini tanımlamak için kullanılabilir, ancak onaylamaz. Örneğin, 5412 tam bir MasterCard'ı temsil etmez, ancak öneriniz bunu ima eder. MasterCard'ların 16 basamaktan başka bir şey olduğuna dair hiçbir kanıt bulamadım. Lütfen talebiniz için bir kaynak sağlamaktan çekinmeyin. Ancak Maestro kartları için bir güncelleme yapılması gerektiğinden bahsetmeniz doğrudur.
senfo

3
@senfo Haklısın, 5412 tam bir Mastercard numarası olmaz. IIN'ler altı basamak uzunluğunda olduğundan, tam bir kart numarası 7 basamak (minimum) olmalı ve Luhn kontrolünü geçmelidir. Mastercard numaralarının 16 basamaktan başka bir şey olduğuna dair “kanıt” gerekmez; nokta şu ki, bugünkü durum ne olursa olsun, gelecekte 17 veya 18 basamaklı kartlar ya da bu konuda 15 için kartlar çıkarabilirler.
alastair

3
Bazı geçerli kartların Luhn algoritmasına göre doğru bir kontrol basamağına sahip olmayacağına inanmakta çok zorlanıyorum. Kart numaralarını basit yazım hataları ve sahtekarlık sahtekarlığı girişimlerine karşı kontrol etmek için kesinlikle her yerde kullanılır. Bunun yerine, oldukça zeki insanların algoritmayı kavramadıklarını gözlemledim ve sadece yanlış hesaplıyorlar.
Rennex

74

Javascript dilinde:

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

Ünite testi:

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

1
@ jolly.exe - Kemanınız tüm testler için tanımsız olarak döner.
Çalışmıyor

@ShadeTreeDeveloper sadece herhangi bir değer girin örn. 372176090165471 metin alanındaki AMAX için
Code Spy

@ jolly.exe Anlıyorum ... Yazarken biçimlendirecek bir şey umuyordum (keyup olayından). Tam sayı girdiğimde keman çalışıyor.
ShadeTreeDeveloper

Girdi biçimlendirme ve doğrulama istediğim yapmak için bu kod biraz yazma sona erdi. Quercusv.github.io/smartForm
ShadeTreeDeveloper

v-pay ve bancontact kart numaralarını nasıl tespit edeceğinizi biliyor musunuz? Teşekkürler
Oleksandr IY

38

Güncelleme: 15 Haziran 2016 (şu anda nihai bir çözüm olarak)

Ben bile bir top oy için vazgeçmek unutmayın, ama bu açıkça ifade etmek için regexps aslında binlerce gerçek BIN kodları ile test çalışır. En önemlisi başlangıç ​​dizelerini (^) kullanmaktır aksi takdirde gerçek dünyada yanlış sonuçlar verir!

JCB ^(?:2131|1800|35)[0-9]{0,}$ Başlangıç noktası : 2131, 1800, 35 (3528-3589)

American Express ^3[47][0-9]{0,}$ ile başlayan: 34, 37

Diners Club ^3(?:0[0-59]{1}|[689])[0-9]{0,}$ ile başlayan: 300-305, 309, 36, 38-39

Visa ^4[0-9]{0,}$ ile başlayan: 4

MasterCard Şununla başlar ^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$ : Noktası 2221-2720, 51-55

Maestro ^(5[06789]|6)[0-9]{0,}$ Maestro daima menzilde büyür: 60-69 başka bir şeyle başlıyor / , ancak 5'in başlangıcı yine de mastercard olarak kodlanmalıdır. Maestro kartları kodun sonunda algılanmalıdır, çünkü bazılarının 60-69 aralığında olması gerekir. Lütfen koda bakın.

Keşfet ^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$ Kodlamak oldukça zor, aşağıdakilerden başlayarak keşfedin: Kodlamak , şununla 6011, 622126-622925, 644-649, 65

In javascript ben bu işlevi kullanın. Bu, bir onkeyup olayına atadığınızda iyi olur ve en kısa sürede sonuç verir.

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

Burada onunla oynayabilirsiniz:

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

PHP için bu işlevi kullanın, bu bazı alt VISA / MC kartlarını da algılar:

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

1
Ve lütfen bunun CC numarası algılama olduğunu ve doğrulama olmadığını unutmayın. Bu ayrıldı, Luhn kontrolü olmalı ...
Janos Szabo

Visa Electron nerede ve Maestro çek bazı durumlarda MasterCard'a neden iade ediyor? MasterCard bunu kontrol etmemeli mi?
BadHorsie

Bu JCB test numarasını tiplerden herhangi biri olarak tanıyamaz (3088514174175777) ve bu test JCB numarasını diners_club (3096278649822922) olarak tanımlar. Bu test kartı numaraları listesinin yine de geçerli olduğu varsayılarak ( freeformatter.com/credit-card-number-generator-validator.html )
Drew

308 veya 309'u başlatmanın bir JCB kartı olabileceğine dair herhangi bir belge yoktur
Janos Szabo

Cc tipi algılama kodu sağlamak için +1, ux için genellikle yapmak istediğiniz şeydir - MC'deki yeni aralık için normal ifadenin küçük bir tweek gerekir: / ^ (5 [1-5] | 222 [1-9] | 22 [3-9] [0-9] | 2 [3-6] [0-9] {2} | 27 [01] [0-9] | 2720) [0-9] {0,} $ /
kinakuta

21
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 # kullanarak Kredi kartı türünü kontrol etme işlevi


19

Şuna bir bak:

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

15

son zamanlarda böyle bir işlevsellik gerekiyordu, ben yakut Zend Framework Kredi Kartı Doğrulayıcı taşıyordu. yakut taş: https://github.com/Fivell/credit_card_validations zend çerçevesi: https://github.com/zendframework/zf2/blob/master/library/Zend/Validator/CreditCard.php

Her ikisi de türü tespit etmek için INN aralıklarını kullanır. Burada INN hakkında okuyabilirsiniz

Buna göre kredi kartını alternatif olarak tespit edebilirsiniz (normal ifadeler olmadan, ancak ön ekler ve olası uzunluk hakkında bazı kurallar beyan ederek)

Bu yüzden en çok kullanılan kartlar için sonraki kurallarımız var

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

}

Daha sonra öneki arayarak ve uzunluğu karşılaştırarak kredi kartı markasını tespit edebilirsiniz. Ayrıca luhn algoritmasını da unutmayın (burada açıklanmaktadır http://en.wikipedia.org/wiki/Luhn ).

GÜNCELLEME

güncellenmiş kurallar listesine buradan ulaşabilirsiniz https://raw.githubusercontent.com/Fivell/credit_card_validations/master/lib/data/brands.yaml


2
Çok açıklayıcı. VISA kartları 13 basamak uzunluğunda olabilir.
Herman Kan

@HermanKan, hiçbir VISA web sitesi 16 uzunluk gerektiğini söylemiyor, uzun zaman önce 13 olabilir, ama bugünlerde değil
Fivell

1
Eski bir destek olduğunu düşünüyorum
Fivell

1
@HermanKan, bir şey daha var, VISA'nın VPay kartları var ve wikipedia'ya göre Visa'nın VPay markası 13 ila 19 basamaktan PAN uzunluklarını belirleyebilir, böylece 16 basamaktan fazla kart numarası görülüyor.
Fivell

1
@Ethan, güncellenmiş yanıtımdaki
Fivell

13

İşte kod projesinde CC ile ilgili her türlü şey için Komple C # veya VB kodu .

  • IsValidNumber
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassesLuhnTest

Bu makale olumsuz yorumlarla birlikte birkaç yıldır yayınlanmıştır.


1
@barett - düzeltildi. bağlantıyı değiştiren 'aspnet' kategorisinden 'validation' kategorisine taşıdıkları anlaşılıyor
Simon_Weaver

2
Bağlantı koptu. Belki de aynı yardımcı programdır? codeproject.com/Articles/20271/…
Josh Noe

Bu kod projesi kodu 2007'den alınmıştır. Uyarı, Güncel olmayabilir.
aron

8

Kompakt javascript sürümü

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

8

Anatoliy'nin PHP'deki cevabı:

 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

İşte php sınıfı işlevi CCtype tarafından CCnumber döndürür.
Bu kod kartı doğrulamıyor veya Luhn algoritmasını çalıştırmıyor sadece bu sayfadaki tabloya göre kredi kartı türünü bulmaya çalışın . CCcard türünü belirlemek için temel olarak CCnumber uzunluğu ve CCcard önekini kullanır.

<?php
class CreditcardType
{
    public static $creditcardTypes = [
        [
            'Name' => 'American Express',
            'cardLength' => [15],
            'cardPrefix' => ['34', '37'],
        ], [
            'Name' => 'Maestro',
            'cardLength' => [12, 13, 14, 15, 16, 17, 18, 19],
            'cardPrefix' => ['5018', '5020', '5038', '6304', '6759', '6761', '6763'],
        ], [
            'Name' => 'Mastercard',
            'cardLength' => [16],
            'cardPrefix' => ['51', '52', '53', '54', '55'],
        ], [
            'Name' => 'Visa',
            'cardLength' => [13, 16],
            'cardPrefix' => ['4'],
        ], [
            'Name' => 'JCB',
            'cardLength' => [16],
            'cardPrefix' => ['3528', '3529', '353', '354', '355', '356', '357', '358'],
        ], [
            'Name' => 'Discover',
            'cardLength' => [16],
            'cardPrefix' => ['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'],
        ], [
            'Name' => 'Solo',
            'cardLength' => [16, 18, 19],
            'cardPrefix' => ['6334', '6767'],
        ], [
            'Name' => 'Unionpay',
            'cardLength' => [16, 17, 18, 19],
            'cardPrefix' => ['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'],
        ], [
            'Name' => 'Diners Club',
            'cardLength' => [14],
            'cardPrefix' => ['300', '301', '302', '303', '304', '305', '36'],
        ], [
            'Name' => 'Diners Club US',
            'cardLength' => [16],
            'cardPrefix' => ['54', '55'],
        ], [
            'Name' => 'Diners Club Carte Blanche',
            'cardLength' => [14],
            'cardPrefix' => ['300', '305'],
        ], [
            'Name' => 'Laser',
            'cardLength' => [16, 17, 18, 19],
            'cardPrefix' => ['6304', '6706', '6771', '6709'],
        ],
    ];

    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

Ödeme işleminin bir parçası olarak kredi kartı türünü saptamaya çalışmayın. Geçerli işlemleri reddetme riskiyle karşı karşıyasınız.

Ödeme işlemcinize bilgi vermeniz gerekiyorsa (örneğin, PayPal kredi kartı nesnesi kart türünü adlandırmayı gerektirir ), mevcut en az bilgiden, ör.

$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.');
}

Bu uygulama (yalnızca ilk iki basamağı kullanarak) tüm ana kart (ve PayPal'ın durumunda desteklenen tüm kartlar) tanımlamak için yeterlidir. Aslında, istisnayı tamamen atlamak ve varsayılan olarak en popüler kart türüne atlamak isteyebilirsiniz. Ödeme ağ geçidinin / işlemcisinin, isteğinize yanıt olarak bir doğrulama hatası olup olmadığını size bildirmesine izin verin.

Gerçek şu ki, ödeme ağ geçidiniz sağladığınız değeri umursamıyor .


1
Bu sadece doğru değil. Kart türlerinin geçirilmesini gerektiren 3 farklı sağlayıcı biliyorum ve bunu geçmezseniz, işlem başarısız olacaktır.
Ed DeGagne

3
@EdDeGagne - "hangi değerin umurunda değil", "iletildiğinde umursamıyor" ile aynı değildir.
Quentin Skousen

İkisini de nerede belirledim? Ben sadece CC türü geçmek SİZİ gerektiren sağlayıcıları olduğunu söyledi, başka bir şey.
Ed DeGagne

Bu karmaşık sorunu basitleştiremezsiniz, ancak genellikle ödeme sağlayıcıları kart türünü önermenizi gerektirmez, tespit etmek için kendi yöntemleri vardır
Janos Szabo

6

Kredi kartının ilk numaraları satıcıyı tahmin etmek için kullanılabilir:

  • Vize: 49,44 veya 47
  • Vize elektronu: 42, 45, 48, 49
  • MasterCard: 51
  • Amex: 34
  • Lokantalar: 30, 36, 38
  • JCB: 35

Bu aralıklar büyük ölçüde güncellendi, Kart satıcı şirketleri postada belirtilenden daha fazla aralık ekledi.
NJInamdar

6

Kart Aralığı Tanıma'da (CRR), bir dizi normal ifade veya diğer sabit kodlu aralıkları kullanan algoritmaların bir dezavantajı, BIN'lerin / IIN'lerin deneyimimde zamanla değişmesidir. Kartların ortak markalaşması devam eden bir komplikasyondur. Farklı Kart Alıcıları / tüccarlar, örneğin coğrafi konumlandırmaya bağlı olarak aynı karta farklı davranmanızı gerektirebilir.

Ayrıca, son birkaç yıl içinde, örneğin daha geniş dolaşımdaki UnionPay kartları ile, mevcut modeller bazen geçtikleri daha geniş aralıklarla araya giren yeni aralıklarla başa çıkmaz.
Bazı aralıkların belirli ülkelerde kullanımı kısıtlandığından, sisteminizin kapsaması gereken coğrafyayı bilmek yardımcı olabilir. Örneğin, 62 aralıkları ABD'de bazı AAA alt aralıklarını içerir, ancak satıcı tabanınız ABD dışındaysa 62'nin tümüne UnionPay olarak davranabilirsiniz.
Ayrıca kartın satıcının bulunduğu yere göre farklı şekilde davranılması istenebilir. Örneğin, bazı İngiltere kartlarına yurtiçinde borç olarak, ancak uluslararası kredi olarak muamele etmek.

Büyük bir Alıcı Banka tarafından yönetilen çok faydalı kurallar vardır. Örneğin, https://www.barclaycard.co.uk/business/files/BIN-Rules-EIRE.pdf ve https://www.barclaycard.co.uk/business/files/BIN-Rules-UK.pdf . (Haziran 2017'den itibaren geçerli bağlantılar, güncellenmiş referansa bağlantı sağlayan kullanıcı sayesinde.) Ancak, bu CRR kurallarının, kart sahibi veren evreni söz konusu tüzel kişi tarafından edinilen satıcılar için geçerli olabileceği uyarısına dikkat edin, örneğin CUP / UPI olarak tanımlanan aralıkları içermez.

Bu yorumlar manyetik şerit (MagStripe) veya PKE (Pan Anahtar Girişi) senaryoları için geçerlidir. ICC / EMV dünyasında durum yine farklı.

Güncelleme: Bu sayfadaki diğer yanıtlar (ve ayrıca bağlı WikiPedia sayfası) her zaman 16 yıl gibi JCB'ye sahiptir. Ancak, şirketimde POS cihazlarımızı ve yazılımlarımızı birden fazla edinen banka ve coğrafyada sertifikalandıran özel bir mühendis ekibimiz var. Bu takımın JCB'den aldığı en son Sertifika Paketi kartlarının 19 uzun PAN için bir geçiş çantası vardı.


Merhaba @CaiqueOliveira, güncellenmiş bağlantılara bakın. Güncellenmiş BIN Kuralları referansına bağlantı sağlayan mac9416 sayesinde.
MikeRoger

1
Güncellenmiş BIN-Rules başvurusu için @ mac9416, teşekkürler.
MikeRoger

5

Swift 2.1 Usman Y'nin cevabının versiyonu. Bir dize değerine göre çağrıyı doğrulamak için bir print ifadesi kullanın

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

}

4

Stripe, kart şeması tespiti için bu harika javascript kütüphanesini sağlamıştır. Birkaç kod parçacığı ekleyeyim ve nasıl kullanılacağını göstereyim.

Öncelikle web sayfanıza şu şekilde ekleyin:

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

İkinci olarak, kart şemasını algılamak için cardType işlevini kullanın.

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

Daha fazla örnek ve demo için referans bağlantıları.

  1. Jquery.payment.js için çizgili blog
  2. Github deposu

4

Hızlı bir şekilde kredi kartı türünü tespit etmek için bir numaralandırma oluşturabilirsiniz.

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 değerini döndüren CreditCardType.cardTypeForCreditCardNumber ("# kart numarası") yöntemini çağırın.


3

JQuery ile benim çözüm:

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 döndürülmesi durumunda kredi kartı türü algılanmaz.

Kredi kartı giriş alanına "kredi kartı" sınıfı eklenmelidir.


1
Mevcut cevapların değişimi.
Gajus

1
Evet, yukarıdaki cevapların kodunu kullandım, İYİLEŞTİRDİM ve buraya gönderdim. Downvote için teşekkürler ...
ZurabWeb

3
(A) bunu mevcut kodda bir iyileştirme olarak önermiş, (b) uygun katkıları yazmış veya (c) normal ifadeleri yazmak için kullandığınız kaynaklara atıfta bulunmuş olmanız gerekir.
Gajus

1
Gajus, inanıyorum ki, topluma o an yapabildiğim gibi yardım ettim, lütfen biri için bir şeyler yapmam gerektiğini söylemeyi bırak. Gerçi ben yardımcı olabilir ne yaptı.
ZurabWeb

3

Kredi kartı biçimlendirme ve telefon numarası biçimlendirme için biraz araştırdım. İyi ipuçları bir sürü bulundu ama hiçbir şey gerçekten benim kesin arzuları uygun bu yüzden kod bu bit oluşturdu . Bu şekilde kullanırsınız:

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

2
// 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
       },

Soru, belirli bir uygulama değil, kredi kartını kontrol etme algoritmasıyla ilgilidir . Bu kod ne işe yarar?
Emil Vikström

2

Sadece küçük bir kaşıkla besleme:

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

        }

    });

2

Burada, Truekart işlev adına göre algılanırsa geri dönen Python'da yazılmış bazı boolean işlevlerine bir örnek verilmiştir .

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

Bir kart numarasının ilk altı basamağı (ilk MII basamağı dahil) yayıncı kimlik numarası (IIN) olarak bilinir . Bunlar, kartı kart sahibine veren kartı veren kurumu tanımlar. Numaranın geri kalanı kart yayıncısı tarafından tahsis edilir. Kart numarasının uzunluğu basamak sayısıdır. Birçok kart düzenleyicisi kartın tümüne IIN ve hesap numarasını yazdırır.

Yukarıdaki gerçeklere dayanarak kart markasını tanımlamak için JAVA kod pasajını tutmak istiyorum .

Örnek kart türleri

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

Kart Önekleri

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

Giriş numarasının verilen öneklerden herhangi birine sahip olup olmadığını kontrol edin.

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

Son olarak, Yardımcı Program yöntemi

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

Referans


1

Kotlin için bunu deneyin. Normal ifade ekleyin ve when ifadesine ekleyin.

private fun getCardType(number: String): String {

        val visa = Regex("^4[0-9]{12}(?:[0-9]{3})?$")
        val mastercard = Regex("^5[1-5][0-9]{14}$")
        val amx = Regex("^3[47][0-9]{13}$")

        return when {
            visa.matches(number) -> "Visa"
            mastercard.matches(number) -> "Mastercard"
            amx.matches(number) -> "American Express"
            else -> "Unknown"
        }
    }

0

İlgili kart satıcılarıyla eşleşen normal ifade kuralları :

  • (4\d{12}(?:\d{3})?) vize için.
  • (5[1-5]\d{14}) MasterCard için.
  • (3[47]\d{13}) AMEX için.
  • ((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?) Maestro için.
  • (3(?:0[0-5]|[68][0-9])[0-9]{11}) Diners Club için.
  • (6(?:011|5[0-9]{2})[0-9]{12}) Discover için.
  • (35[2-8][89]\d\d\d{10}) JCB için.

Bence JCB için normal ifade yanlış. 3528 ve 3589 arasındaki ilk dört basamağın tümü kabul edilmelidir, ancak 3570 kabul edilmez.
Gabe

0

Kredi kartı türünü numaradan tespit etmek için https://github.com/bendrucker/creditcards-types/ adresini kullanıyorum . Karşılaştığım bir sorun, 6011 1111 1111 1117 test numarasını keşfetmek.

dan https://www.cybersource.com/developers/other_resources/quick_references/test_cc_numbers/ bunu 6011. başlar Ama creditcards-türlerinden olsun sonuç "Maestro" olduğu için bir numara keşfetmek görebilirsiniz. Konuyu yazara açtım. Çok yakında cevap verdi ve bu pdf belgesini sağladı https://www.discovernetwork.com/downloads/IPP_VAR_Compliance.pdf Dokümandan, 6011 1111 1111 1117'nin kredi kartı keşfetme aralığına düşmediğini açıkça görebiliyoruz.


Aynı sorunu yaşıyorum, bu sorunu çözdünüz mü?
lucasvm1980

@ lucasvm1980 Ben Discovernetwork.com pdf dosyasının daha güvenilir olduğunu düşünüyorum. Ve 6011 1111 1111 1117 sayısı sadece bir test numarasıdır, gerçek bir kredi kartı bu numaraya sahip değildir. Bu yüzden endişelenmenize gerek yok.
yuxiaomin

Bazı Discover kartı ile bazı hata var gibi görünüyor, geçerli numara denedim ve ben de bu hatayı alıyorum.
lucasvm1980

@ lucasvm1980 github'da bir numara verebilir ve bir sorun gönderebilir misiniz?
yuxiaomin

0

Bunu deneyin.

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
}

Kullanımı.

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

0
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) {

            }
        });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.