0
votes

I've been trying to figure out this Luhns method of validating a Credit Card but I can't seem to figure it out. I NEED to use methods and cannot use arrays so I'm totally stumped.

Here's the Luhns check:

A credit card number must have between 13 and 16 digits. It must start with: ■ 4 for Visa cards ■ 5 for Master cards ■ 37 for American Express cards ■ 6 for Discover cards

  1. Double every second digit from right to left. If doubling of a digit results in a two-digit number, add up the two digits to get a single-digit number.
  2. Now add all single-digit numbers from Step a.
  3. Add all digits in the odd places from right to left in the card number.
  4. Sum the results from Step b and Step c.
  5. If the result from Step d is divisible by 10, the card number is valid; otherwise, it is invalid. For example, the number 4388576018402626 is invalid, but the number 4388576018410707 is valid.

My issue is that I'm still learning methods (Total beginner. I tried to learn to code once last year and gave up, but I've managed to get this far this time) and I can't figure out how to use these methods to both do step 4 and 5 from the Luhn check.

Could someone please try to help me out? Thank you!!

public static boolean isValid(String x) {
    return false; // Stub method    
}

public static void AddResults() {

}

public static void OddDigits(String s) {
    int sum = 0;
    for (int index = 0; index < s.length(); index ++) {
        if (index % 2 != 0) {
            sum = sum + Character.getNumericValue(s.charAt(index));
        }
    }
    return;
}

public static int DoubleToSingle(int x) { // Adds up the digits in a two-digit number. 
    if (x < 10) {
        return x;
    } 
    else {
        int firstDigit = x % 10;
        int secondDigit = (int)(x / 10);
        return firstDigit + secondDigit;
    }
}

public static void Doubling(String s) {
    int sum = 0;
    for (int index = s.length() - 1; index > 0; index-= 2) {
        int parse = Character.getNumericValue(s.charAt(index));
        if (parse > 9) {
        sum = sum + DoubleToSingle(parse);
        }
        else {
            sum = sum + parse;
        }
    }

    return;
}

public static boolean CheckLength(String s) {
    if (s.length() < 13 || s.length() > 16) { // If the cc number is smaller than 13 digits or larger than 16 digits, it's invalid
        return false;
    }
    else {
        return true;
    }
}

public static String ReadString(Scanner s) { // Creating a string method. (Using it to practice creating methods)
    String x = s.nextLine();
    return x;
}

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    System.out.println("Please input a valid Credit Card number: ");
    String CC = ReadString(input);

    if (isValid(CC) == true) {
        System.out.println(CC + " is valid.");
    } else {
        System.out.println(CC + " is invalid.");
    }       
    input.close();
}
1

1 Answers

1
votes

Comments about your code:

  • Java naming convention is for method names to start with lowercase letter, like your isValid method.

  • In the doubleToSingle method, x is an int, and 10 is an int literal, so x / 10 will be an int, with the result truncated, which means there is no need for this cast: (int)(x / 10)

  • Since doubleToSingle method can handle single-digit numbers, there is no need for the caller (doubling method) to handle it too, so eliminate the if (parse > 9) test.

  • Counting digits from the right works like this:

     5th digit       Odd places:
     ↓ 3rd digit       Don't double these digits, just sum them
     ↓ ↓ 1st digit
     ↓ ↓ ↓
    999999
    ↑ ↑ ↑
    ↑ ↑ 2nd digit    Even places, aka "every second digit from right":
    ↑ 4th digit        Double these digits, combine digits when
    6th digit          two-digit number, then sum them
    

    The doubling method starts at the last index, not the second-last as it should, and it skips the first index, which it shouldn't. The loop should be:

    for (int index = s.length() - 2; index >= 0; index -= 2)
    
  • The doubling method do need to actually double the number (parse * 2) before calling the doubleToSingle method.

  • The oddDigits method counts odd/even from the left, when it should count from the right.

    Remove the if (index % 2 != 0) test, and use similar loop as used in doubling method:

    for (int index = s.length() - 1; index >= 0; index -= 2)
    
  • The doubling and oddDigits methods should return the sum, otherwise what's the point?

If think the lack of return value from the doubling and oddDigits methods is what got you stuck, so I'll let you work on the rest of your code from here.


Although the following code is beyond your current skill level, I want to show it so you have something to look forward to, being able to understand and eventually write code like it.

public static boolean isValid(String cc) {
    if (! cc.matches("(?=[456]|37)[0-9]{13,16}"))
        return false;
    int sum = 0;
    for (int i = cc.length() - 1, pos = 1; i >= 0; i--, pos++) {
        int digit = cc.charAt(i) - '0';
        sum += (pos % 2 == 1/*odd*/ ? digit : digit < 5 ? digit * 2 : digit * 2 - 9);
    }
    return (sum % 10 == 0);
}

It tests all the conditions listed in the question, even the "It must start with" part that you haven't started on yet. At your skill level, you should probably use s.startsWith("xx") instead of the matches(...) regular expression used here.