简体   繁体   中英

Converting a long int into separate digits and reverse populating into a vector

First of all this is a school project about credit card number validations. Basically I am trying to convert a long int (the CC number) into a vector so I can manipulate each digit as required. I am doing it by using the %10 way. Since this will end up with my vector having the number from right to left (backwards), I am setting the vector in increments starting from ccNum.size()-1 and working backwards so that the values in the vector are in the same order as the user input. The problem is that first values that are processed (so the last 9 or so digits of input) are being put in the vector incorrectly. I've tried restructuring the loop, copying into an array and then reversing it into the vector, and various other things that my mind just can't keep track of. I tried to comment my code as best as I could to outline what is going on, here it is:

public static void main(String[] args) {

    long creditCardNumber = 0;
    Vector<Integer> ccNum = new Vector<Integer>(13,3);
    Vector<Integer> oddNum = new Vector<Integer>(6,1);
    Vector<Integer> evenNum = new Vector<Integer>(6,1);

    creditCardNumber = getInput(creditCardNumber);
    int size = getSize(creditCardNumber);

     //Pre-populate the vector so that I can add values starting from behind
     //this makes it so that the credit card number isn't backwards. I also
     //did it so that it matches the size of the input to prevent false values
             //Yes, I verified the getSize method works.
     for (int k = 0; k < size; k++) {
         ccNum.add(k);
     }

     //I made a copy of the variable so I don't screw it up in the loop
     long ccNumber = creditCardNumber;

     //THIS IS WHERE THE PROBLEM IS.
     for (int j = 0; ccNumber > 0; j++){
         //on the first iteration, set the final index of ccNum array to
         //final value of input using %10
         if (j == 0){
         ccNum.set(ccNum.size() - 1, (int) ccNumber % 10);
         ccNumber /= 10;
         //This just prints the value of ccNumber afterwards so that I can
         //keep track of whats going on and make sure everything is "working"
         System.out.println(ccNumber);
         } else {
         //Here I am continuously setting the values going backwards
         //I end up with the same amount of values as the input but some
         //are wrong
         ccNum.set(ccNum.size() - (j+1), (int) ccNumber % 10);
         ccNumber /= 10;
         System.out.println(ccNumber);
         }
     }
     //Here is where I print out all the values in the ccNum vector.
     for (int l = 0; l < size; l++) {
         System.out.print(ccNum.get(l));
     }
    System.out.println("");

    for (int i = 0; i < ccNum.size() - 1; i ++) {
        if (i % 2 == 0) {
            evenNum.add(getDigit(ccNum.get(i)));
        } else {
            oddNum.add(ccNum.get(i));
        }
    }

    int prefix = getPrefix(ccNum);
    int sumEven = sumOfDoubleEvenPlace(evenNum);
    int sumOdd = sumOfOddPlace(oddNum);

    if (isValid(ccNum, sumEven, sumOdd, size, prefix)) {
        System.out.printf("%d: is valid", creditCardNumber);
    } else {
        System.out.printf("%d: is invalid", creditCardNumber);
    }
}

private static int sumOfOddPlace(Vector<Integer> oddNum) {
    int sum = 0;
    for (int i = 0; i < oddNum.size() - 1; i++) {
        sum += oddNum.get(i);
    }
    return sum;
}

private static int sumOfDoubleEvenPlace(Vector<Integer> evenNum) {
    int sum = 0;
    for (int i = 0; i < evenNum.size() - 1; i++) {
        sum += evenNum.get(i);
    }
    return sum;
}

private static int getDigit(int x) {
    int y = x*2;

    if (y < 10) {
        return y;
    } else {
        int sum = 0;
        while (y > 0) {
            sum += y % 10;
            y /= 10;
        }
        return sum;
    }
}

private static int getPrefix(Vector<Integer> ccNum) {
    if (ccNum.get(0) == 4) {
    return 4;
    } else if (ccNum.get(0) == 5) {
        return 5;
    } else if (ccNum.get(0) == 6) {
        return 6;
    } else if (ccNum.get(0) == 3 && ccNum.get(1) == 7) {
        return 37;
    } else {
        return 0;
    }
}

private static int getSize(long creditCardNumber) {

    int size = (int)(Math.log10(creditCardNumber)+1);
    return size;
}

private static long getInput(long creditCardNumber){
    Scanner input = new Scanner(System.in);
    System.out.print("Enter a credit card number: ");
    creditCardNumber = input.nextLong();
    input.close();
    return creditCardNumber;
}

private static boolean isValid(Vector<Integer> ccNum, int sumEven, int sumOdd, int size, int prefix) {

    if (size < 13 || size > 16) {
        return false;
    } else if (prefixMatched(prefix) == false) {
        return false;
    } else if ((sumEven + sumOdd) % 10 != 0) {
        return false;
    } else {
    return true;
    }

}

private static boolean prefixMatched(int prefix) {
    if (prefix == 4 || prefix == 5 || prefix == 6 || prefix == 37) {
        return true;
    } else {
        return false;
    }
}

Here is the output:

Enter a credit card number: 4388576018410707
438857601841070
43885760184107
4388576018410
438857601841
43885760184
4388576018
438857601
43885760
4388576
438857
43885
4388
438
43
4
0
438857601249-2-16-3
4388576018410707: is invalid

As You can see, the first half of the number comes out correctly (the last half to be looped). If anybody has a solution that'd be awesome.

For future reference for other people who may get stuck - this is what i ended up doing, looks cleaner as well, Thanks for the help everyone.

public class CreditCardNumberValidation {

    public static void main(String[] args) {

        long creditCardNumber = 0;
         //Using ArrayLists because it makes it easier to manipulate data later
        ArrayList<Integer> ccNum = new ArrayList<Integer>();
        ArrayList<Integer> oddNum = new ArrayList<Integer>();
        ArrayList<Integer> evenNum = new ArrayList<Integer>();
        //Getting input in different method to clean up the code
        creditCardNumber = getInput(creditCardNumber);
        int size = getSize(creditCardNumber);
         //Split creditCardNumber into separate integers and store in ArrayList
         long ccNumber = creditCardNumber;
         for (int j = 0; ccNumber > 0; j++){
             ccNum.add((int) (ccNumber % 10));
             ccNumber /= 10;
         }
         //Reverse the collection so that the numbers are in order
         Collections.reverse(ccNum);
         //Using the main List, even and odd numbers are sorted
        for (int i = 0; i < ccNum.size(); i ++) {
            if (i % 2 == 0) {
                evenNum.add(getDigit(ccNum.get(i)));
            } else {
                oddNum.add(ccNum.get(i));
            }
        }

        int prefix = getPrefix(ccNum);
        int sumEven = sumOfDoubleEvenPlace(evenNum);
        int sumOdd = sumOfOddPlace(oddNum);

        if (isValid(ccNum, sumEven, sumOdd, size, prefix)) {
            System.out.printf("%d is valid", creditCardNumber);
        } else {
            System.out.printf("%d is invalid", creditCardNumber);
        }
    }

    private static int sumOfOddPlace(ArrayList<Integer> oddNum) {
        int sum = 0;
        for (int i = 0; i < oddNum.size(); i++) {
            sum += oddNum.get(i);
        }
        return sum;
    }

    private static int sumOfDoubleEvenPlace(ArrayList<Integer> evenNum) {
        int sum = 0;
        for (int i = 0; i < evenNum.size(); i++) {
            sum += evenNum.get(i);
        }
        return sum;
    }

    private static int getDigit(int x) {
        int y = x*2;

        if (y < 10) {
            return y;
        } else {
            int sum = 0;
            while (y > 0) {
                sum += y % 10;
                y /= 10;
            }
            return sum;
        }
    }

    private static int getPrefix(ArrayList<Integer> ccNum) {
        if (ccNum.get(0) == 4) {
        return 4;
        } else if (ccNum.get(0) == 5) {
            return 5;
        } else if (ccNum.get(0) == 6) {
            return 6;
        } else if (ccNum.get(0) == 3 && ccNum.get(1) == 7) {
            return 37;
        } else {
            return 0;
        }
    }

    private static int getSize(long creditCardNumber) {
        //Easy way of getting the size of an integer without modifying it
        return (int)(Math.log10(creditCardNumber)+1);
    }

    private static long getInput(long creditCardNumber){
        Scanner input = new Scanner(System.in);
        System.out.print("Enter a credit card number: ");
        creditCardNumber = input.nextLong();
        input.close();
        return creditCardNumber;
    }

    private static boolean isValid(ArrayList<Integer> ccNum, int sumEven, int sumOdd, int size, int prefix) {
        // Check size, prefix, and sum, if all tests pass return true
        if (size < 13 || size > 16) {
            return false;
        } else if (prefixMatched(prefix) == false) {
            return false;
        } else if ((sumEven + sumOdd) % 10 != 0) {
            return false;
        } else {
        return true;
        }   
    }

    private static boolean prefixMatched(int prefix) {
        if (prefix == 4 || prefix == 5 || prefix == 6 || prefix == 37) {
            return true;
        } else {
            return false;
        }
    }

}

Try to replace

(int) ccNumber % 10

by

(int) (ccNumber % 10)

If you cast to int first and then do the modulo 10, it won't work when the int value overflows.

I recomend you using ArrayList like in my listing. My function returns simple arraylist of integers that was in Long.

public List<Integer>getCardNumbers(Long longCardNumber){
 String cardNumber = longCardNumber.toString();
 List<Integer> intCardNumberList = new ArrayList<Integer>();
    for(int i=0;i<cardNumber.length();i++){
        intCardNumberList.add(Integer.parseInt(String.valueOf(cardNumber.charAt(i))));
    }
    return intCardNumberList;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM