Credit card type and validation

credit-card, java, loops

Solution

I do card type detection with an enum:

package com.gabrielbauman.gist;

import java.util.regex.Pattern;

public enum CardType {

    UNKNOWN,
    VISA("^4[0-9]{12}(?:[0-9]{3}){0,2}$"),
    MASTERCARD("^(?:5[1-5]|2(?!2([01]|20)|7(2[1-9]|3))[2-7])\\d{14}$"),
    AMERICAN_EXPRESS("^3[47][0-9]{13}$"),
    DINERS_CLUB("^3(?:0[0-5]\\d|095|6\\d{0,2}|[89]\\d{2})\\d{12,15}$"),
    DISCOVER("^6(?:011|[45][0-9]{2})[0-9]{12}$"),
    JCB("^(?:2131|1800|35\\d{3})\\d{11}$"),
    CHINA_UNION_PAY("^62[0-9]{14,17}$");

    private Pattern pattern;

    CardType() {
        this.pattern = null;
    }

    CardType(String pattern) {
        this.pattern = Pattern.compile(pattern);
    }

    public static CardType detect(String cardNumber) {

        for (CardType cardType : CardType.values()) {
            if (null == cardType.pattern) continue;
            if (cardType.pattern.matcher(cardNumber).matches()) return cardType;
        }

        return UNKNOWN;
    }

}

You can then do `CardType.detect("cardnumbergoeshere")` and you'll get back CardType.VISA, etc.

There's a unit test over at the gist.

For validation, I have:

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

That should do it.

Edit: fixed escape characters in DINERS_CLUB

Problem

I would like to run a program that can determine the validation and type of credit card number based of number entered. Compiler shows notification that there is an error in my coding but I cannot detect where is it. The program is also cannot be run. Below is the coding, ``` import java.util.*; public class CreditCard { public static void main(String args[]) { String CType;(String number) { if (number.startsWith("4")) return "Visa"; else if (number.startsWith("5")) return "MasterCard"; else if (number.startsWith("6")) return "Discover"; else if (number.startsWith("37")) return "American Express"; else return "Unknown type"; }; Scanner input = new Scanner(System.in); System.out.println("Enter a credit card number: "); long number = input.nextLong(); long total = sumOfEvenPlaces(number) + (sumOfOddPlaces(number)*2); if (isValid(total)) { System.out.println("The "+CType+" card number is valid"); } else { System.out.println("The "+CType+" card number is invalid."); } } public static boolean isValid(long total) { if (total % 10 != 0) { } else { return true; } return false; } public static int sumOfEvenPlaces(long number) { int sum = 0; int remainder; while (number % 10 != 0 || number / 10 != 0) { remainder = (int) (number % 10); sum = sum + getDigit(remainder * 2); number /= 100; } return sum; } public static int getDigit(int number) { if (number > 9) { return (number % 10 + number / 10); } return number; } public static int sumOfOddPlaces(long number) { int sum = 0; int remainder; number /= 10; while (number % 10 != 0 || number / 10 != 0) { remainder = (int) (number % 10); sum = sum + getDigit(remainder * 2); number /= 100; } return sum; } } ```

Original source