5

I need to do a Credit card number validation.

When I googled this I found the org.apache.commons.validator.CreditCardValidator. But seems like it is not working correctly. When I pass a non-digit character also it porvides true.

Code for Apache CreditCardValidator:

String ccNumber = "378282246310005";
CreditCardValidator creditCardValidator = new CreditCardValidator();
if(!creditCardValidator.isValid(ccNumber)) throw new Exception("Credit Card Number is not a valid one!");

Then, I wrote following methods to validate credit card numbers based on the card type and the card number (using the luhn's algorithm).

CardType validator (null if an invalid card type)

public String getCCType(String ccNumber){

        String visaRegex        = "^4[0-9]{12}(?:[0-9]{3})?$";
        String masterRegex      = "^5[1-5][0-9]{14}$";
        String amexRegex        = "^3[47][0-9]{13}$";
        String dinersClubrRegex = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$";
        String discoverRegex    = "^6(?:011|5[0-9]{2})[0-9]{12}$";
        String jcbRegex         = "^(?:2131|1800|35\\d{3})\\d{11}$";
        String commonRegex      = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$";

        try {
            ccNumber = ccNumber.replaceAll("\\D", "");
            return (ccNumber.matches(visaRegex) ? "VISA" : ccNumber.matches(masterRegex) ? "MASTER" :ccNumber.matches(amexRegex) ? "AMEX" :ccNumber.matches(dinersClubrRegex) ? "DINER" :ccNumber.matches(discoverRegex) ? "DISCOVER"  :ccNumber.matches(jcbRegex) ? "JCB":null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

CardNumber validator using Luhn's algorithem.

public boolean isValidCardNumber(String ccNumber){

        try {
            ccNumber = ccNumber.replaceAll("\\D", "");
            char[]      ccNumberArry    = ccNumber.toCharArray();

            int         checkSum        = 0;
            for(int i = ccNumberArry.length - 1; i >= 0; i--){

                char            ccDigit     = ccNumberArry[i];

                if((ccNumberArry.length - i) % 2 == 0){
                    int doubleddDigit = Character.getNumericValue(ccDigit) * 2;
                    checkSum    += (doubleddDigit % 9 == 0 && doubleddDigit != 0) ? 9 : doubleddDigit % 9;

                }else{
                    checkSum    += Character.getNumericValue(ccDigit);
                }

            }

            return (checkSum != 0 && checkSum % 10 == 0);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return false;
    }

I want to know,

  1. Is there any other thrid party class to validate the credit cards other than the org.apache one?
  2. Is there any issue with the my code? (I tested it for several times. So far so good. I just want to know if you could spot something that I didn't.)

References : How do you detect Credit card type based on number?

Community
  • 1
  • 1
ironwood
  • 8,936
  • 15
  • 65
  • 114
  • Can you post the code regarding the Apache CreditCardValidator? Fixing that will be easier than writing your own IMHO. – Thihara Oct 22 '13 at 06:28
  • I added it Thihara. I'm also looking for a recommended third party class that has been thoroughly tested and verified. – ironwood Oct 22 '13 at 06:33
  • 1
    Is the posted code's credit card number valid or invalid? What is the test case that failed and caused you to look else where? Apache commons is widely used so it's a good choice, sorry I'm not aware of any other libs for this kind of validation. – Thihara Oct 22 '13 at 06:45
  • @Thihara : There must be an error with the Apache validator jar that I was using or build issue of my project (my project is running under maven). Now I got the latest one and it's working fine. Thanks for the support. – ironwood Oct 23 '13 at 12:19

3 Answers3

1

I did this a long time ago, Sorry Code is in C. Easily Convertible. Hope this will help you.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int CardNoChecker(unsigned long long int Number)
{
        int dijts=0;
        int Ans=0;
        {
            unsigned long long int k=1;
            while(Number%k!=Number)
            {
                    dijts=dijts+1;
                    k=k*10;
            }
        }
    {
        int i=1;
        int Product=0;
        int Sum=0;
        for(i=dijts;i>=1;i--)
        {
                if(i%2==0)
                {
                    if((Number%10)*2<10)
                    Product = Product + (  Number % 10  ) * 2 ;
                    else
                    {
                        int No=(Number%10)*2;
                        Product = Product + No/10;
                        Product = Product + No%10;
                    }
                }
                else
                {
                    Sum = Sum + (  Number  % 10     ) ;
                }
                Number=Number /10;
        }
        Ans = Sum + Product ;
    }
    if(Ans%10==0)
    return (1);
    else
    return (0);
}

int main()
{
    unsigned long long int CardNO;
    int valid=0;
    while(!valid)
    {
        int CnV=0;
        int VC=0;
        int AE=0;
        int MC=0;
        printf("Enter Card NO : ");
        scanf("%llu",&CardNO);
        if(CardNO/1000000000000==4 || CardNO/1000000000000000==4)
        {
            VC=1;
        }
        else if(CardNO/10000000000000==34 ||CardNO/10000000000000==37)
        {
            AE=1;
        }
        else if(CardNO/100000000000000==51 || CardNO/100000000000000==52 || CardNO/100000000000000==53 || CardNO/100000000000000==54 || CardNO/100000000000000==55)
        {
            MC=1;
        }
        CnV=CardNoChecker(CardNO);
        if(CnV && MC )
         printf("This is a Valid Master Card\n\n");
         else if(CnV && VC )
         printf("This is a Valid Visa Card\n\n");
         else if(CnV && AE )
         printf("This is a Valid American Express Card\n\n");
         else
        printf("Card is Not Valid'\n\n");
    }

    return (0);
}
Ayub Khan
  • 896
  • 2
  • 14
  • 17
  • Thank you Ayub. But I'm looking for a recomended third party class. I decided the scratching as the last option. – ironwood Oct 23 '13 at 11:36
1

Have a look to Luhn algorithm https://en.wikipedia.org/wiki/Luhn_algorithm

 public static void main(String[] args) {
    boolean isValid = checkCC("4561 2612 1234 5467");
    System.out.println(isValid);
}

private static boolean checkCC(String input)  {
    String purportedCC = input.replaceAll(" ", "");
    int sum = 0;

    for (int i = 0; i < purportedCC.length(); i++) {
        int cardNum = Integer.parseInt(
                Character.toString(purportedCC.charAt(i)));

        if ((purportedCC.length() - i) % 2 == 0) {
            cardNum = cardNum * 2;

            if (cardNum > 9) {
                cardNum = cardNum - 9;
            }
        }

        sum += cardNum;
    }
    return sum % 10 == 0;
}
Oleg Maksymuk
  • 441
  • 4
  • 10
0

You can find custom implantation of credit card validator here which is doing both credit card number validation plus credit card type detection,

http://www.esupu.com/credit-card-validator-java/

Supun Sameera
  • 2,683
  • 3
  • 17
  • 14
  • I've also done it sameera as mentioned in the question. And similar implementation as you've mentioned in your reference has been also implemented in another project that I'm using. But I'm looking for a third party class that has been tested to be recommended. – ironwood Oct 23 '13 at 11:41
  • @Supun Sameera. Unfortunately, your link is broken now – valerybodak Nov 23 '15 at 09:47