2

I'm relatively new to java and am trying to break my code down as much as possible. This question is really on how to organize methods to work together

My credit card validator works if checkSum() code is written in the validateCreditCard() method. I think it's weird 'cause it works when called by the checkDigitControl() method

I used these sources for the program's logic:

To Check ~ https://www.creditcardvalidator.org/articles/luhn-algorithm

To Generate ~ https://en.wikipedia.org/wiki/Luhn_mod_N_algorithm

Here's my code(I apologize in advance if it's rather clumsy)

public class CreditCards {

    public static void main(String[] args) {
        long num;

        num = genCreditCard();
        boolean bool = validateCreditCard(num);

    }
    // Validity Check
    public static boolean validateCreditCard(long card) {
        String number = card+"";
        String string=null;

        int i;
        for(i=0; i<number.length()-1; i++) {//Populate new string, leaving out last digit.
            string += number.charAt(i)+"";
        }
        String checkDigit = number.charAt(i)+"";// Stores check digit.

        long sum = checkSum(string);// Program works if this line is swapped for the code below(from checkSum)
        //**********************************************************************
//        int[] digits = new int[number.length()];
//        int lastIndex = digits.length-1;
//        int position=2; int mod=10;
//        int sum=0;
//
//        for(int j=lastIndex; j>=0; j--) {// Populate array in REVERSE
//            digits[j] = Integer.parseInt(number.charAt(j)+"");
//            digits[j] *= ( (position%2 == 0) ? 2: 1 );// x2 every other digit FROM BEHIND
//            position++;
//
//            digits[j] = ( (digits[j] > 9) ? (digits[j] / mod)+(digits[j] % mod) : digits[j] );//Sums integers of  double-digits
//            sum += digits[j];
//        }
        //**********************************************************************
        sum *= 9;
        string = sum+"";
        string = string.charAt(string.length()-1)+"";// Last digit of result.

        return (string.equals(checkDigit));
    }

    public static long genCreditCard() {
        String number = "34";// American Express(15 digits) starts with 34 or 37
        for(int i=0; i<12; i++)
            number += (int)(Math.random() * 10) + "";// Add 12 random digits 4 base.

        number += checkDigitControl(number);// Concat the check digit.
        System.out.println(number);
        return Long.parseLong(number);
    }
    // Algorithm to calculate the last/checkSum digit.
    public static int checkDigitControl(String number) {
        int i;
        for(i=0; i<5; i++)
            ++i;
        int sum = checkSum(number);
        return 10 - sum%10;// Returns number that makes checkSum a multiple of 10.
    }

    public static int checkSum(String number) {
        int[] digits = new int[number.length()];
        int lastIndex = digits.length-1;
        int position=2; int mod=10;
        int sum=0;

        for(int j=lastIndex; j>=0; j--) {// Populate array in REVERSE
            digits[j] = Integer.parseInt(number.charAt(j)+"");
            digits[j] *= ( (position%2 == 0) ? 2: 1 );// x2 every other digit FROM BEHIND
            position++;

            digits[j] = ( (digits[j] > 9) ? (digits[j] / mod)+(digits[j] % mod) : digits[j] );//Sums integers of  double-digits
            sum += digits[j];
        }
        return sum;
    }

}

Thx in advance, sorry if this isn't the right format; it's also my 1st Stackoverflow post ¯\_(ツ)_/¯

J. Doe
  • 41
  • 3
  • 1
    Wow! I had no idea Stackoverflow was so useful. Thanks a bunch for the help. – J. Doe Aug 10 '17 at 18:43
  • I still have 1 question though, if the problem was the assignment to `null`, then why didn't affect it when `string` was used in the `validateCreditCard()` method, only when it was passed into the `checkSum()` – J. Doe Aug 10 '17 at 18:53
  • 1
    Because in the code you commented you used `number` variable instead of `string` variable. And number was the actual credit card number. In `checkSum` method contrarily you passed string variable that was wrong. Glad to help you, and if the answer help you consider to accepting it. It's how stackoverflow works. https://stackoverflow.com/help/someone-answers – amicoderozer Aug 11 '17 at 07:43
  • 1
    And for the next times you can comment directly under the answer, so the guy who answered will receive the notification of your message. If you comment here under your question you have to tag the person with `@username` if you want that he receives the notification of your message. https://meta.stackexchange.com/questions/125208/when-exactly-do-i-get-comment-notifications – amicoderozer Aug 11 '17 at 07:50
  • 1
    Thx for the stackoverflow tip. I'll comment under **your** answer – J. Doe Aug 12 '17 at 15:06

1 Answers1

0

You are initializing the variable string with null value:

String string=null;

And in the following for you are adding every char of the card number to this string.

for(i=0; i<number.length()-1; i++) {
    string += number.charAt(i)+"";
}

But this will result in the variable string to be null + cardnumbers, because you didn't initialize the String string, and the value null is converted to the string "null" (Concatenating null strings in Java)

This will fix you code:

String string = new String();

Note, this code:

for(i=0; i<number.length()-1; i++) {
     string += number.charAt(i)+"";
}

can be easily replace by this line that does the same thing:

number = number.substring(0, number.length() -1);

If you switch to this code just pass number to checkSum method

amicoderozer
  • 2,046
  • 6
  • 28
  • 44
  • I still have 1 question though, if the problem was the assignment to null, then why didn't affect it when string was used in the `validateCreditCard()` method, only when it was passed into the `checkSum()`. Sorry, I still don't quite understand your reply to that. – J. Doe Aug 12 '17 at 15:07
  • In `validateCreditCard` method after `long sum = checkSum(string);` (commented code) you used `number` variable to get the digits of the credit card (`int[] digits = new int[number.length()];`) because you copied the code from `checkSum` method where `number` variable was the parameter (`checkSum(String number)`). In `validateCreditCard` you declared another `number` variable (`String number = card+"";`) that contains the number of the credit card, and hence not null, and used instead of `string` variable. So when you use the commented code you don't use `string` variable but `number` variable – amicoderozer Aug 16 '17 at 07:33