Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

I have this code, for checking the vailidity of a credit card number and it works, but it fails the JUnit test for the incorrect

I have this code, for checking the vailidity of a credit card number and it works, but it fails the JUnit test for the incorrect numbers.

The valid prefixes are: 4, 5, 37 and 6

Everything else (including no prefix) should fail (for example: 1, 2, 7... etc)

So there is something wrong with the "ValidPrefix" method.

Here is the code:

package edu.wit.cs.comp1050;

import java.util.Scanner;

/** * Solution to Programming Assignment 2a when it runs prompts the user to enter * a credit card number and display whether the number is valid or invalid. * * @author Rose Levine * */ public class PA2a {

/** * Error to display if input contains non-numeric characters */ public static final String ERR_NON_NUMERIC = "Non-numeric input";

/** * Error to display if input is too short */ public static final String ERR_SHORT = "Input is too short";

/** * Error to display if input is too long */ public static final String ERR_LONG = "Input is too long";

/** * Error to display if input contains an invalid prefix */ public static final String ERR_BAD_PREFIX = "Invalid prefix";

/** * Array of valid single-digit prefixes */ public static final int[] PREFIXES_ONE_DIGIT = { 4, 5, 6 };

/** * Array of valid double-digit prefixes */ public static final int[] PREFIXES_TWO_DIGIT = { 37 };

/** * Minimum input length */ public static final int LENGTH_MIN = 13;

/** * Maximum input length */ public static final int LENGTH_MAX = 16;

/** * Returns true if the supplied argument contains only numeric digits (0-9) * * @param s input string * @return true if input contains only numeric digits */ public static boolean isOnlyNumbers(String s) { for (Character c : s.toCharArray()) { if (!Character.isDigit(c)) { return false; } } return true; }

/** * Return the numeric value that the supplied character represents '0' -> 0 '1' * -> 1 ... '9' -> 9 * * @param c input character (assumed to be a digit) * @return integer represented by the input */ public static int digitCharToInt(char c) { return c - '0'; }

/** * Returns the numeric value that the supplied characters represent in sequence * (c1 is tens place, c2 is ones) '00' -> 0 '01' -> 1 ... '10' -> 10 '11' -> 11 * ... '90' -> 90 '91' -> 91 '99' -> 99 * * @param c1 tens place digit (assumed to be a digit) * @param c2 ones place digit (assumed to be a digit) * @return integer represented by the inputs */ public static int digitCharToInt(char c1, char c2) { return 10 * digitCharToInt(c1) + digitCharToInt(c2); }

/** * Returns true if the supplied integer is contained within the array of * integers * * @param needle item to search for * @param haystack valid list in which to search * @return true if needle is in haystack */ public static boolean inArray(int needle, int[] haystack) { for (int x : haystack) { if (x == needle) { return true; } } return false; }

/** * Returns true if the supplied string begins with a valid prefix * * @param s credit card number (assumed to be comprised only of digits) * @return true if begins with a valid CC prefix */ public static boolean validPrefix(String s) { if (s == null || s.isEmpty()) return false; int oneCharPrefix = digitCharToInt(s.charAt(0)); int twoCharPrefix = digitCharToInt(s.charAt(0), s.charAt(1)); return inArray(oneCharPrefix, PREFIXES_ONE_DIGIT) || inArray(twoCharPrefix, PREFIXES_TWO_DIGIT); }

/** * Returns the number of digits in an integer * * @param num number (assumed to be non-negative) * @return number of digits in the number */ public static int numDigits(int num) { if (num == 0) return 1; int n = 0; while (num != 0) { num /= 10; n++; } return n; }

/** * Returns the digit in the specified "place" of an input number, where 0 is the * ones, 1 is the ten's, ... * * f(1234, 0) = 4 f(1234, 1) = 3 f(1234, 2) = 2 f(1234, 3) = 1 * * @param num input number (assumed to be non-negative) * @param place place from which to extract the digit (assumed to be [0, * #digits-1]) * @return digit extracted */ public static int getDigitInPlace(int num, int place) { int n = 0; while (place != n) { num /= 10; n++; } return num % 10; }

/** * Returns a single digit number resulting from repeatedly adding the digits of * a number until it is reduced to a single digit... 5678 => 5 + 6 + 7 + 8 = 26 * => 2 + 6 = 8 * * @param num number (assumed to be non-negative) * @return single-digit from repeated sums */ public static int reduceToDigit(int num) { while (num > 9) { int n = numDigits(num); int sum = 0; while (n-- > 0) { sum += getDigitInPlace(num, n); } num = sum; } return num; }

/** * Sums every second digit, right to left. If doubling results in a * double-digit, add up the digits to produce a single. 4388576018402626 => 2*2 * = 4 +2*2 = 4 +2*4 = 8 +2*1 = 2 +2*6 = 12 => 3 +2*5 = 10 => 1 +2*8 = 16 => 7 * +2*4 = 8 = 37 * * @param s input string (assumed to be only digits) * @return sum of doubled evens */ public static int sumOfDoubleEvens(String s) { int sum = 0; for (int i = s.length() - 2; i >= 0; i -= 2) { sum += reduceToDigit(digitCharToInt(s.charAt(i)) * 2); }

return sum; }

/** * Sums every odd digit, right to left. 4388576018402626 => 6+6+0+8+0+7+8+3=38 * * @param s input string (assumed to be only digits) * @return sum of odds */ public static int sumOfOdds(String s) { int sum = 0; for (int i = s.length() - 1; i >= 0; i -= 2) { sum += digitCharToInt(s.charAt(i)); }

return sum; }

/** * Returns true if the sum of the doubled sum of even digits + sum of odd digits * is divisible by 10. * * 4388576018402626: 37 + 38 = 75 % 10 != 0 => false 5117275325077359: 18 + 42 = * 60 % 10 == 0 => true * * @param s input string (assumed to be only digits) * @return true if passes the Luhn check */ public static boolean luhnCheck(String s) { int sum = sumOfDoubleEvens(s) + sumOfOdds(s); return sum % 10 == 0; }

/** * Inputs a credit card number and outputs either input-validation error or * validation status of the card number * * @param args command-line arguments, ignored */ public static void main(String[] args) { Scanner in = new Scanner(System.in);

System.out.print("Enter a credit card number: "); String ccNumber = in.nextLine();

System.out.print("Status: "); if (!isOnlyNumbers(ccNumber)) { System.out.println(ERR_NON_NUMERIC); } else if (ccNumber.length() > LENGTH_MAX) { System.out.println(ERR_LONG); } else if (ccNumber.length() < LENGTH_MIN) { System.out.println(ERR_SHORT); } else if (!validPrefix(ccNumber)) { System.out.println(ERR_BAD_PREFIX); } else if (!luhnCheck(ccNumber)) { System.out.println("card is invalid"); } else { System.out.println("card is valid"); }

in.close(); }

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

OCA Oracle Database SQL Exam Guide Exam 1Z0-071

Authors: Steve O'Hearn

1st Edition

1259585492, 978-1259585494

More Books

Students also viewed these Databases questions

Question

What are the impacts of urbanization on runoff quantity?

Answered: 1 week ago

Question

Number of days sale in receivables Please see the attached image.

Answered: 1 week ago

Question

What is cultural tourism and why is it growing?

Answered: 1 week ago

Question

Is there any dispute that this is the cause?

Answered: 1 week ago