- return "VISA card" if substr($number,0,1) == "4";
- return "MasterCard" if substr($number,0,1) == "5";
- return "Discover card" if substr($number,0,1) == "6";
- return "American Express card" if substr($number,0,2) == "37";
- return "Diner's Club, Transmedia, or other dining/entertainment card" if substr($number,0,1) == "3";
+ return "Switch"
+ if $number =~ /^49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})[\dx]{10}([\dx]{2,3})?$/o
+ || $number =~ /^564182[\dx]{10}([\dx]{2,3})?$/o
+ || $number =~ /^6(3(33[0-4][0-9])|759[0-9]{2})[\dx]{10}([\dx]{2,3})?$/o;
+
+ return "VISA card" if $number =~ /^4[\dx]{12}([\dx]{3})?$/o;
+
+ return "MasterCard"
+ if $number =~ /^5[1-5][\dx]{14}$/o
+ || ( $number =~ /^36[\dx]{12}/ && $Country =~ /^(US|CA)$/oi );
+
+ return "Discover card"
+ if $number =~ /^6011[\dx]{12}$/o
+ || $number =~ /^65[\dx]{14}$/o
+ || ( $number =~ /^622[\dx]{13}$/o && $Country !~ /^(CN)$/oi );
+
+ return "American Express card" if $number =~ /^3[47][\dx]{13}$/o;
+
+ return "Diner's Club/Carte Blanche"
+ if $number =~ /^3(0[0-5]|[68][\dx])[\dx]{11}$/o;
+
+ return "enRoute" if $number =~ /^2(014|149)[\dx]{11}$/o;
+
+ return "JCB" if $number =~ /^(3[\dx]{4}|2131|1800)[\dx]{11}$/o;
+
+ return "BankCard" if $number =~ /^56(10[\dx][\dx]|022[1-5])[\dx]{10}$/o;
+
+ return "Solo"
+ if $number =~ /^6(3(34[5-9][0-9])|767[0-9]{2})[\dx]{10}([\dx]{2,3})?$/o;
+
+ return "China Union Pay"
+ if $number =~ /^622[\dx]{13}$/o;
+
+ return "Laser"
+ if $number =~ /^6(304|7(06|09|71))[\dx]{12,15}$/o;
+