Regex for determining credit cards in Android

I'm really new to regex, but I think my problem might go beyond that. As the name says, I'm trying to determine if a credit card is a visa, amex, Master Card, etc.

I looked at this post which gave a regex for each of the map types:

How do you determine the type of credit card based on the number?

This is the code I used then, but it does nothing:

etCCNum.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { Log.d("DEBUG", "beforeTextChanged : "+s); } @Override public void afterTextChanged(Editable s) { Pattern pattern = Pattern.compile("^6(?:011|5[0-9]{2})[0-9]{3,}$"); Log.d("DEBUG", "afterTextChanged : "+s); String ccNum = s.toString(); Matcher matcher = pattern.matcher(ccNum); if(matcher.matches()){ Log.d("DEBUG", "afterTextChanged : discover"); } } }); 

The regular expression in the pattern.compile function is used to identify Discover cards according to the message above. I noticed that I really can’t get anything to work except “^” in the regular expression (ie (“^ 4” is visa, “^ 6001”), however this is clearly not enough for editing. I thought it might be a problem with my java but i am running java 7

I may need to ask a new question, but I am also interested in how a regular expression can be used to make the right choice between different credit cards, even if the user comes back and edits the number (xxxx xxxx xxxx xxxx)

EDIT: Added DEBUG magazine on top. My input is a few numbers that should be associated with certain credit cards. I am currently using the Eagle Eye code below (which should also work to detect that the input is ONE of the card types):

final ArrayList listOfPattern = new ArrayList ();

 String ptVisa = "^4[0-9]{6,}$"; listOfPattern.add(ptVisa); String ptMasterCard = "^5[1-5][0-9]{5,}$"; listOfPattern.add(ptMasterCard); String ptAmeExp = "^3[47][0-9]{5,}$"; listOfPattern.add(ptAmeExp); String ptDinClb = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"; listOfPattern.add(ptDinClb); String ptDiscover = "^6(?:011|5[0-9]{2})[0-9]{3,}$"; listOfPattern.add(ptDiscover); String ptJcb = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"; listOfPattern.add(ptJcb); etCCNum.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { Log.d("DEBUG", "beforeTextChanged : "+s); } @Override public void afterTextChanged(Editable s) { Log.d("DEBUG", "afterTextChanged : "+s); String ccNum = s.toString(); for(String p:listOfPattern){ if(ccNum.matches(p)){ Log.d("DEBUG", "afterTextChanged : discover"); break; } } } }); 

Log:

 01-29 15:16:41.932 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 01-29 15:16:41.933 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 4 01-29 15:16:46.815 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 4 01-29 15:16:46.816 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 01-29 15:16:50.925 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 01-29 15:16:50.926 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 6 01-29 15:16:51.542 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 6 01-29 15:16:51.543 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 60 01-29 15:16:51.883 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 60 01-29 15:16:51.883 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 600 01-29 15:16:52.928 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 600 01-29 15:16:52.929 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 6001 01-29 15:16:55.781 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 6001 01-29 15:16:55.782 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 600 01-29 15:16:56.206 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 600 01-29 15:16:56.206 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 60 01-29 15:16:57.659 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 60 01-29 15:16:57.660 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 605 01-29 15:16:59.297 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 605 01-29 15:16:59.298 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 60 01-29 15:16:59.527 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 60 01-29 15:16:59.527 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 6 01-29 15:17:00.314 26194-26194/com.xx D/DEBUG﹕ beforeTextChanged : 6 01-29 15:17:00.314 26194-26194/com.xx D/DEBUG﹕ afterTextChanged : 65 

You expect the "open" magazine to be released several times for the different numbers that I entered. The above log shows how I print the first few digits of a visa card and a search card.

CHANGE ANSWER TO FOUND: I just did not dial enough numbers for a recognizable card!

+7
java android regex
source share
2 answers

According to one of the answers in the stream, the cards can be checked based on the following data.

Visa: ^4[0-9]{6,}$ Visa card numbers start at 4.

MasterCard: ^5[1-5][0-9]{5,}$ MasterCard numbers start with numbers 51 through 55, but this will only determine MasterCard credit cards; There are other cards issued using the MasterCard system that do not fall into this IIN range.

American Express: ^3[47][0-9]{5,}$ American Express card numbers start at 34 or 37.

Diners Club: ^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Diners Club card numbers start from 300 to 305, 36 or 38. There are cards Diners Club that start with 5 and have 16 digits. This is a joint venture between Diners Club and MasterCard and should be treated as MasterCard.

Open: ^6(?:011|5[0-9]{2})[0-9]{3,}$ Open the card numbers starting with 6011 or 65.

JCB: ^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ JCB cards start with 2131, 1800 or 35.

So, you need to create a separate template for each case. You can do the following.

 ArrayList<String> listOfPattern=new ArrayList<String>(); String ptVisa = "^4[0-9]{6,}$"; listOfPattern.add(ptVisa); String ptMasterCard = "^5[1-5][0-9]{5,}$"; listOfPattern.add(ptMasterCard); String ptAmeExp = "^3[47][0-9]{5,}$"; listOfPattern.add(ptAmeExp); String ptDinClb = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"; listOfPattern.add(ptDinClb); String ptDiscover = "^6(?:011|5[0-9]{2})[0-9]{3,}$"; listOfPattern.add(ptDiscover); String ptJcb = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"; listOfPattern.add(ptJcb); } 

and then

 @Override public void afterTextChanged(Editable s) { Log.d("DEBUG", "afterTextChanged : "+s); String ccNum = s.toString(); for(String p:listOfPattern){ if(ccNum.matches(p)){ Log.d("DEBUG", "afterTextChanged : discover"); break; } } } 

And for your last question, the following thread will help you.

Format credit card in a text editor in android

EDIT:

If the card number is 16 digits, for example, after applying the logic to add spaces after 4 digits, you need to remove these spaces when processing the actual card number. Then only the above logic will work.

Hope this helps.

+14
source share

Use the following class to validate your card.

 public class Validator { public static final byte VISA = 0; public static final byte MASTERCARD = 1; public static final byte AMEX = 2; public static final byte DINERS_CLUB = 3; public static final byte CARTE_BLANCHE = 4; public static final byte DISCOVER = 5; public static final byte ENROUTE = 6; public static final byte JCB = 7; public static boolean validate(final String credCardNumber, final byte type) { String creditCard = credCardNumber.trim(); boolean applyAlgo = false; switch (type) { case VISA: // VISA credit cards has length 13 - 15 // VISA credit cards starts with prefix 4 if (creditCard.length() >= 13 && creditCard.length() <= 16 && creditCard.startsWith("4")) { applyAlgo = true; } break; case MASTERCARD: // MASTERCARD has length 16 // MASTER card starts with 51, 52, 53, 54 or 55 if (creditCard.length() == 16) { int prefix = Integer.parseInt(creditCard.substring(0, 2)); if (prefix >= 51 && prefix <= 55) { applyAlgo = true; } } break; case AMEX: // AMEX has length 15 // AMEX has prefix 34 or 37 if (creditCard.length() == 15 && (creditCard.startsWith("34") || creditCard .startsWith("37"))) { applyAlgo = true; } break; case DINERS_CLUB: case CARTE_BLANCHE: // DINERSCLUB or CARTEBLANCHE has length 14 // DINERSCLUB or CARTEBLANCHE has prefix 300, 301, 302, 303, 304, // 305 36 or 38 if (creditCard.length() == 14) { int prefix = Integer.parseInt(creditCard.substring(0, 3)); if ((prefix >= 300 && prefix <= 305) || creditCard.startsWith("36") || creditCard.startsWith("38")) { applyAlgo = true; } } break; case DISCOVER: // DISCOVER card has length of 16 // DISCOVER card starts with 6011 if (creditCard.length() == 16 && creditCard.startsWith("6011")) { applyAlgo = true; } break; case ENROUTE: // ENROUTE card has length of 16 // ENROUTE card starts with 2014 or 2149 if (creditCard.length() == 16 && (creditCard.startsWith("2014") || creditCard .startsWith("2149"))) { applyAlgo = true; } break; case JCB: // JCB card has length of 16 or 15 // JCB card with length 16 starts with 3 // JCB card with length 15 starts with 2131 or 1800 if ((creditCard.length() == 16 && creditCard.startsWith("3")) || (creditCard.length() == 15 && (creditCard .startsWith("2131") || creditCard .startsWith("1800")))) { applyAlgo = true; } break; default: throw new IllegalArgumentException(); } if (applyAlgo) { return validate(creditCard); } return false; } public static boolean validate(String creditCard) { // 4 9 9 2 7 3 9 8 7 1 6 // 6 // 1 x 2 = 2 = (0 + 2) = 2 // 7 // 8 x 2 = 16 = (1 + 6) = 7 // 9 // 3 x 2 = 6 = (0 + 6) = 6 // 7 // 2 x 2 = 4 = (0 + 4) = 4 // 9 // 9 X 2 = 18 = (1 + 8) = 9 // 4 // 6+2+7+7+9+6+7+4+9+9+4 = 70 // return 0 == (70 % 10) int sum = 0; int length = creditCard.length(); for (int i = 0; i < creditCard.length(); i++) { if (0 == (i % 2)) { sum += creditCard.charAt(length - i - 1) - '0'; } else { sum += sumDigits((creditCard.charAt(length - i - 1) - '0') * 2); } } return 0 == (sum % 10); } private static int sumDigits(int i) { return (i % 10) + (i / 10); } public final static boolean isValidEmail(CharSequence target) { return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches(); } 

}

0
source share

All Articles