Check Credit Card Validity using Luhn Algorithm

浪子不回头ぞ 提交于 2019-11-27 13:19:36
Nicholas Ng

You can freely import the following code:

public class Luhn
{
    public static boolean Check(String ccNumber)
    {
            int sum = 0;
            boolean alternate = false;
            for (int i = ccNumber.length() - 1; i >= 0; i--)
            {
                    int n = Integer.parseInt(ccNumber.substring(i, i + 1));
                    if (alternate)
                    {
                            n *= 2;
                            if (n > 9)
                            {
                                    n = (n % 10) + 1;
                            }
                    }
                    sum += n;
                    alternate = !alternate;
            }
            return (sum % 10 == 0);
    }
}

Link reference: https://github.com/jduke32/gnuc-credit-card-checker/blob/master/CCCheckerPro/src/com/gnuc/java/ccc/Luhn.java

Google and Wikipedia are your friends. Instead of long-array I would use int-array. On Wikipedia following java code is published (together with detailed explanation of Luhn algorithm):

   public static boolean check(int[] digits) {
     int sum = 0;
     int length = digits.length;
     for (int i = 0; i < length; i++) {

       // get digits in reverse order
       int digit = digits[length - i - 1];

       // every 2nd number multiply with 2
       if (i % 2 == 1) {
           digit *= 2;
       }
       sum += digit > 9 ? digit - 9 : digit;
     }
     return sum % 10 == 0;
   }

You should work on your input processing code. I suggest you to study following solution:

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    boolean repeat;
    List<Integer> digits = new ArrayList<Integer>();

    do {
        repeat = false;
        System.out.print("Enter your Credit Card Number : ");
        String input = in.next();

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c < '0' || c > '9') {
                repeat = true;
                digits.clear();
                break;
            } else {
                digits.add(Integer.valueOf(c - '0'));
            }
        }
    } while (repeat);

    int[] array = new int[digits.size()];
    for (int i = 0; i < array.length; i++) {
        array[i] = Integer.valueOf(digits.get(i));
    }
    boolean valid = check(array);
    System.out.println("Valid: " + valid);
}

I took a stab at this with Java 8:

public static boolean luhn(String cc) {
    final boolean[] dbl = {false};
    return cc
            .chars()
            .map(c -> Character.digit((char) c, 10))
            .map(i -> ((dbl[0] = !dbl[0])) ? (((i*2)>9) ? (i*2)-9 : i*2) : i)
            .sum() % 10 == 0;
}

Add the line

            .replaceAll("\\s+", "")

Before

            .chars()

If you want to handle whitespace.

Seems to produce identical results to

return LuhnCheckDigit.LUHN_CHECK_DIGIT.isValid(cc);

From Apache's commons-validator.

There are two ways to split up your int into List<Integer>

  1. Use %10 as you are using and store it into a List
  2. Convert to a String and then take the numeric values

Here are a couple of quick examples

public static void main(String[] args) throws Exception {
    final int num = 12345;
    final List<Integer> nums1 = splitInt(num);
    final List<Integer> nums2 = splitString(num);
    System.out.println(nums1);
    System.out.println(nums2);
}

private static List<Integer> splitInt(int num) {
    final List<Integer> ints = new ArrayList<>();
    while (num > 0) {
        ints.add(0, num % 10);
        num /= 10;
    }
    return ints;
}

private static List<Integer> splitString(int num) {
    final List<Integer> ints = new ArrayList<>();
    for (final char c : Integer.toString(num).toCharArray()) {
        ints.add(Character.getNumericValue(c));
    }
    return ints;
}

I'll use 5 digit card numbers for simplicity. Let's say your card number is 12345; if I read the code correctly, you store in array the individual digits:

array[] = {1, 2, 3, 4, 5}

Since you already have the digits, in sumOfOddPlace you should do something like

public static int sumOfOddPlace(long[] array) {
    int result = 0;
    for (int i = 1; i < array.length; i += 2) {
        result += array[i];
    }
    return result;
}

And in sumOfDoubleEvenPlace:

public static int sumOfDoubleEvenPlace(long[] array) {
    int result = 0;
    for (int i = 0; i < array.length; i += 2) {
        result += getDigit(2 * array[i]);
    }
    return result;
}

this is the luhn algorithm implementation which I use for only 16 digit Credit Card Number

if(ccnum.length()==16){
    char[] c = ccnum.toCharArray();
    int[] cint = new int[16];
    for(int i=0;i<16;i++){
        if(i%2==1){
            cint[i] = Integer.parseInt(String.valueOf(c[i]))*2;
            if(cint[i] >9)
                cint[i]=1+cint[i]%10;
        }
        else
            cint[i] = Integer.parseInt(String.valueOf(c[i]));
    }
    int sum=0;
    for(int i=0;i<16;i++){
        sum+=cint[i];
    }
    if(sum%10==0)
        result.setText("Card is Valid");
    else
        result.setText("Card is Invalid");
}else
    result.setText("Card is Invalid");

If you want to make it use on any number replace all 16 with your input number length.

It will work for Visa number given in the question.(I tested it)

Here's my implementation of the Luhn Formula.

/**
 * Runs the Luhn Equation on a user inputed CCN, which in turn
 * determines if it is a valid card number.
 * @param c A user inputed CCN.
 * @param cn The check number for the card.
 * @return If the card is valid based on the Luhn Equation.
 */
public boolean luhn (String c, char cn)
{
    String card = c;
    String checkString = "" + cn;
    int check = Integer.valueOf(checkString);

    //Drop the last digit.
    card = card.substring(0, ( card.length() - 1 ) );

    //Reverse the digits.
    String cardrev = new StringBuilder(card).reverse().toString();

    //Store it in an int array.
    char[] cardArray = cardrev.toCharArray();
    int[] cardWorking = new int[cardArray.length];
    int addedNumbers = 0;

    for (int i = 0; i < cardArray.length; i++)
    {
        cardWorking[i] = Character.getNumericValue( cardArray[i] );
    }

    //Double odd positioned digits (which are really even in our case, since index starts at 0).

    for (int j = 0; j < cardWorking.length; j++)
    {
        if ( (j % 2) == 0)
        {
            cardWorking[j] = cardWorking[j] * 2;
        }
    }

    //Subtract 9 from digits larger than 9.

    for (int k = 0; k < cardWorking.length; k++)
    {
        if (cardWorking[k] > 9)
        {
            cardWorking[k] = cardWorking[k] - 9;
        }
    }

    //Add all the numbers together.
    for (int l = 0; l < cardWorking.length; l++)
    {
        addedNumbers += cardWorking[l];
    }

    //Finally, check if the number we got from adding all the other numbers
    //when divided by ten has a remainder equal to the check number.
    if (addedNumbers % 10 == check)
    {
        return true;
    }
    else
    {           
        return false;
    }
}

I pass in the card as c which I get from a Scanner and store in card, and for cn I pass in checkNumber = card.charAt( (card.length() - 1) );.

Okay, this can be solved with a type conversions to string and some Java 8 stuff. Don't forget numbers and the characters representing numbers are not the same. '1' != 1

public static int[] longToIntArray(long cardNumber){

return Long.toString(cardNumber).chars()
    .map(x -> x - '0') //converts char to int 
    .toArray();  //converts to int array
}

You can now use this method to perform the luhn algorithm:

  public static int luhnCardValidator(int cardNumbers[]) {
                int sum = 0, nxtDigit;
                for (int i = 0; i<cardNumbers.length; i++) {
                    if (i % 2 == 0) 
                      nxtDigit  = (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : nxtDigit * 2;
                    sum += nxtDigit;
                }
                return (sum % 10);
            }
private static int luhnAlgorithm(String number){
    int n=0;
    for(int i = 0; i<number.length(); i++){
        int x = Integer.parseInt(""+number.charAt(i));
        n += (x*Math.pow(2, i%2))%10;
        if (x>=5 && i%2==1) n++;
    }
    return n%10;
}
user3328528
public class Creditcard {

    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        String cardno = sc.nextLine();

        if(checkType(cardno).equals("U")) //checking for unknown type
          System.out.println("UNKNOWN");
        else
          checkValid(cardno); //validation 
}

private static String checkType(String S)
{
    int AM=Integer.parseInt(S.substring(0,2));
    int D=Integer.parseInt(S.substring(0,4)),d=0;
    for(int i=S.length()-1;i>=0;i--)
    {
        if(S.charAt(i)==' ')
            continue;
        else
            d++;
    }
    if((AM==34 || AM==37) && d==15)
        System.out.println("AMEX");
    else if(D==6011 && d==16)
        System.out.println("Discover");
    else if(AM>=51 && AM<=55 && d==16)
        System.out.println("MasterCard");
    else if(((S.charAt(0)-'0')==4)&&(d==13 || d==16)) 
        System.out.println("Visa");
    else
        return "U";
    return "";
}

private static void checkValid(String S) // S--> cardno
{
    int i,d=0,sum=0,card[]=new int[S.length()];

    for(i=S.length()-1;i>=0;i--)
    {
        if(S.charAt(i)==' ')
            continue;
        else
            card[d++]=S.charAt(i)-'0';
    }

    for(i=0;i<d;i++)
    {
        if(i%2!=0)
        {
            card[i]=card[i]*2;
            if(card[i]>9)
                sum+=digSum(card[i]);
            else
                sum+=card[i];
        }
        else
            sum+=card[i];
    }
    if(sum%10==0)
        System.out.println("Valid");
    else    
        System.out.println("Invalid");

}

public static int digSum(int n)
{
    int sum=0;
    while(n>0)
    {
        sum+=n%10;
        n/=10;
    }
    return sum;
}
}

Here is the implementation of Luhn algorithm.

public class LuhnAlgorithm {

/**
 * Returns true if given card number is valid
 *
 * @param cardNum Card number
 * @return true if card number is valid else false
 */
private static boolean checkLuhn(String cardNum) {
    int cardlength = cardNum.length();
    int evenSum = 0, oddSum = 0, sum;
    for (int i = cardlength - 1; i >= 0; i--) {
        System.out.println(cardNum.charAt(i));
        int digit = Character.getNumericValue(cardNum.charAt(i));
        if (i % 2 == 0) {
            int multiplyByTwo = digit * 2;
            if (multiplyByTwo > 9) {
                /* Add two digits to handle cases that make two digits after doubling */
                String mul = String.valueOf(multiplyByTwo);
                multiplyByTwo = Character.getNumericValue(mul.charAt(0)) + Character.getNumericValue(mul.charAt(1));
            }
            evenSum += multiplyByTwo;
        } else {
            oddSum += digit;
        }
    }
    sum = evenSum + oddSum;
    if (sum % 10 == 0) {
        System.out.println("valid card");
        return true;
    } else {
        System.out.println("invalid card");
        return false;
    }

}

public static void main(String[] args) {
    String cardNum = "4071690065031703";
    System.out.println(checkLuhn(cardNum));
}

}
public class LuhnAlgorithm {

/**
 * Returns true if given card number is valid
 *
 * @param cardNum Card number
 * @return true if card number is valid else false
 */
private static boolean checkLuhn(String cardNum) {
    int cardlength = cardNum.length();
    int evenSum = 0, oddSum = 0, sum;
    for (int i = cardlength - 1; i >= 0; i--) {
        System.out.println(cardNum.charAt(i));
        int digit = Character.getNumericValue(cardNum.charAt(i));
        if (i % 2 == 0) {
            int multiplyByTwo = digit * 2;
            if (multiplyByTwo > 9) {
                /* Add two digits to handle cases that make two digits after doubling */
                String mul = String.valueOf(multiplyByTwo);
                multiplyByTwo = Character.getNumericValue(mul.charAt(0)) + Character.getNumericValue(mul.charAt(1));
            }
            evenSum += multiplyByTwo;
        } else {
            oddSum += digit;
        }
    }
    sum = evenSum + oddSum;
    if (sum % 10 == 0) {
        System.out.println("valid card");
        return true;
    } else {
        System.out.println("invalid card");
        return false;
    }

}

public static void main(String[] args) {
    String cardNum = "8112189875";
    System.out.println(checkLuhn(cardNum));
}

}

Hope it may works.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!