Credit Card Issuer Checking in Java


The challenge

Given a credit card number we can determine who the issuer/vendor is with a few basic knowns.

Complete the function getIssuer() that will use the values shown below to determine the card issuer for a given card number. If the number cannot be matched then the function should return the string Unknown.

| Card Type  | Begins With          | Number Length |
|------------|----------------------|---------------|
| AMEX       | 34 or 37             | 15            |
| Discover   | 6011                 | 16            |
| Mastercard | 51, 52, 53, 54 or 55 | 16            |
| VISA       | 4                    | 13 or 16      |

Examples

getIssuer(4111111111111111) == "VISA"
getIssuer(4111111111111) == "VISA"
getIssuer(4012888888881881) == "VISA"
getIssuer(378282246310005) == "AMEX"
getIssuer(6011111111111117) == "Discover"
getIssuer(5105105105105100) == "Mastercard"
getIssuer(5105105105105106) == "Mastercard"
getIssuer(9111111111111111) == "Unknown"

The solution in Java code

Option 1:

public class CreditCardChecker {
  public static String getIssuer(String cardNumber) {
    if ((cardNumber.startsWith("34") || cardNumber.startsWith("37")) && cardNumber.length()==15)
      return "AMEX";
    if (cardNumber.startsWith("6011") && cardNumber.length()==16)
      return "Discover";
    if ((cardNumber.startsWith("51") || cardNumber.startsWith("52") || cardNumber.startsWith("53") || cardNumber.startsWith("54") || cardNumber.startsWith("55")) && cardNumber.length()==16)
      return "Mastercard";
    if (cardNumber.startsWith("4") && (cardNumber.length()==13 || cardNumber.length()==16))
      return "VISA";
    return "Unknown";
  }
}

Option 2:

import static java.util.regex.Pattern.matches;
public class CreditCardChecker {
  public static String getIssuer(String cn) {
    if (matches("^3[4|7].{13}$", cn)) return "AMEX";
    if (matches("^6011.{12}$", cn)) return "Discover";
    if (matches("^5[1-5].{14}$", cn)) return "Mastercard";
    if (matches("^4.{12}(...)?$", cn)) return "VISA";
    return "Unknown";
  }
}

Option 3:

public class CreditCardChecker {
  public static String getIssuer(String cardNumber) {
    String visa = "4+(\\d{15}|\\d{12})";
    String amex = "(34|37)+\\d{13}";
    String discover = "6011+\\d{12}";
    String mastercard = "(51|52|53|54|55)+\\d{14}";
    String result = "Unknown";
    if (cardNumber.matches(visa)) return "VISA";
    if (cardNumber.matches(amex)) return "AMEX";
    if (cardNumber.matches(discover)) return "Discover";
    if (cardNumber.matches(mastercard)) return "Mastercard";
    return result;
  }
}

Test cases to validate our solution

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class SolutionTest {
    @Test
    public void issuerTests() {
        assertEquals("VISA",       CreditCardChecker.getIssuer("4111111111111111"));
        assertEquals("AMEX",       CreditCardChecker.getIssuer("378282246310005"));
        assertEquals("Unknown",    CreditCardChecker.getIssuer("9111111111111111"));
        assertEquals("Mastercard", CreditCardChecker.getIssuer("5105105105105100"));
    }
}

Additional test cases

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
import java.util.concurrent.ThreadLocalRandom;


public class SolutionTest {
    @Test
    public void issuerTests() {
        assertEquals("VISA",       CreditCardChecker.getIssuer("4111111111111111"));
        assertEquals("VISA",       CreditCardChecker.getIssuer("4111111111111"));
        assertEquals("VISA",       CreditCardChecker.getIssuer("4012888888881881"));
        assertEquals("Unknown",    CreditCardChecker.getIssuer("41111111111111"));
        assertEquals("Unknown",    CreditCardChecker.getIssuer("411111111111111"));

        assertEquals("AMEX",       CreditCardChecker.getIssuer("378282246310005"));
        assertEquals("AMEX",       CreditCardChecker.getIssuer("348282246310005"));

        assertEquals("Discover",   CreditCardChecker.getIssuer("6011111111111117"));

        assertEquals("Mastercard", CreditCardChecker.getIssuer("5105105105105100"));
        assertEquals("Mastercard", CreditCardChecker.getIssuer("5105105105105106"));
        assertEquals("Mastercard", CreditCardChecker.getIssuer("5205105105105106"));
        assertEquals("Mastercard", CreditCardChecker.getIssuer("5305105105105106"));
        assertEquals("Mastercard", CreditCardChecker.getIssuer("5405105105105106"));
        assertEquals("Mastercard", CreditCardChecker.getIssuer("5505105105105106"));

        assertEquals("Unknown",    CreditCardChecker.getIssuer("9111111111111111"));
        assertEquals("Unknown",    CreditCardChecker.getIssuer("5605105105105106"));
    }
        @Test
    public void randomTests() {
        assertEquals("VISA",       CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(4000000000000000L ,4999999999999999L ))));
        assertEquals("VISA",       CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(4000000000000L    ,4999999999999L ))));
        
        assertEquals("AMEX",       CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(340000000000000L  ,349999999999999L ))));
        assertEquals("AMEX",       CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(370000000000000L  ,379999999999999L ))));
        
        assertEquals("Discover",   CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(6011000000000000L ,6011999999999999L ))));

        assertEquals("Mastercard", CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(5100000000000000L ,5599999999999999L ))));
        
        assertEquals("Unknown",    CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(0L ,3999999999999L ))));
        assertEquals("Unknown",    CreditCardChecker.getIssuer(String.valueOf(ThreadLocalRandom.current().nextLong(6012999999999999L ,9999999999999999L ))));

    }
}