Search code examples
javaluhn

How can I verify card PAN in text string?


I have string with any text. It can be like this - "abcdef 123456789521 zxcvb", and - "45651256", and - "asdad 564654 sddsf 4". I want to search in text PAN number, that can be different length, and than verify it with luhn algorithm. I know, that I can to find it by regx, but it require expresion like this - "Pattern.compile("[A-Z]{5}[0-9]{4}[A-Z]{1}");. But I don't know how many characters and digits and in what order my string will contains. May be anyone know how to do it? Any advice?


Solution

  • I assume that by PAN you mean credit card number (see PAN on wikipedia).

    According to that article, the numbers must be between 8 and 19 digits long. Thus, you search your text for numbers with a length in that interval, store them and check them with the Luhn algorithm. Here's an implementation that finds numbers between 8-19 digits in length and performs the Luhn-check:

    import java.util.ArrayList;
    import java.util.regex.Pattern;    
    import java.util.regex.Matcher;
    
    public class main {
        public static void main(String[] args) {
            String text = "helloWor4712389062l648977135536d 239012390oife234923 uiwed wq12893129038";
    
            ArrayList<String> result = getPossiblePANs(text);
            for(String pan : result) {
                System.out.print("Possible PAN: " + pan);
                if(luhnCheck(pan))
                    System.out.println(" is valid!");
                else
                    System.out.println(" is INVALID!");
            }
        }
    
    
        static ArrayList<String> getPossiblePANs(String text){  //Numbers w. 8-19 digits
            ArrayList<String> res = new ArrayList<>();
            Pattern p = Pattern.compile("\\d{8,19}+");
            Matcher m = p.matcher(text);
            while(m.find())
                res.add(m.group());
            return res;
        }
    
        static boolean luhnCheck(String cardNumber){
            if(cardNumber.length() < 8 || cardNumber.length() > 19)
                return false;
            int sum = 0;
            int begin = cardNumber.length() - 2;
            for(int i = begin; i >= 0; i-=2){
                int number = Integer.parseInt(cardNumber.substring(i, i+1)) * 2;
                if(number > 9) sum += (number - 9);
                else sum += number;
            }
            return (sum % 10) == 0;
        }
    }
    

    Possible PAN: 4712389062 is INVALID!
    Possible PAN: 648977135536 is INVALID!
    Possible PAN: 239012390 is INVALID!
    Possible PAN: 12893129038 is valid!