Homework 6
Due: Nov 2 , prior to 11:59:59 PM
Overview
Credit card companies and banks use built-in numerical security measures when creating the account numbers on credit cards. This means that there are only certain valid credit card numbers, and validity can quickly be detected by using various mathematical operations.
In this assignment, you will write Java methods to implement a simple validation algorithm on a credit card number. Note that this algorithm is purely made up; don’t try to use it to create fake credit card numbers!
In completing this assignment, you will learn to:
- Implement static methods in Java
- Assemble multiple methods into a single program
- Pass arrays as arguments to methods
- Write methods that use arrays as return values
Code Understandability and Readability
In addition to writing code that correctly implements the specification, you are also asked to write code that is easy to read and understand.
In particular, part of your score on this assignment will be determined by:
Variable naming: Variables should have meaningful names that indicate what they represent, using full English words or common abbreviations, e.g. "wins" or "votes" instead of "w" or "vot".
Appearance: The code should be formatted so that indentation and spacing make it easy to understand which parts of the code are within the bodies of if-statements and loops. Additionally, there should be spacing between variables and operators to make it easy to read each individual line of code.
Setup
Start by making a new directory for homework 6.
Next, copy a file containing some (fictional) credit card numbers into the directory you just created. The file is available on Unix in the file
/home/gtowell/Public/CS113/HW6/cc.txt
Note that the "/" at the beginning of this file is important. Be sure to get everything in this name or the copy will fail. Use cp or scp to copt this file to your Unix account or laptop, respectively.
Reading a File
There are many ways to read from files in Java; the method you should use builds up one the FileReader you used in HW4 since again, you will be reading character by character. To get you started, here is some code to read a single character from the first line of cc.txt.
import java.io.FileReader;
public class VerifyOne {
public static int[] readANum(FileReader fr) {
try {
if (!fr.ready()) { // there is nothing more to read.
return new int[0];
}
int[] res = new int[1];
res[0] = fr.read();
return res;
} catch (Exception ee) {
return new int[0];
}
}
public static void main(String[] args) {
try {
FileReader fr = new FileReader("cc.txt");
int[] card = readANum(fr);
if (card.length > 0) {
System.out.println(card[0]);
}
} catch (Exception ioe) {
System.out.println("Error " + ioe);
}
}
}
In the code above you open the FileReader in the main method, but then use it in the readANum method. Java, being Java, requires that opening a File reader be surrounded by a try..catch because the opening could fail if, for example, the file did not exist.
In the readANum function we again need to wrap everything in a try..catch because the reading could fail (for example, the file was deleted between the time it was opened and the time you read from it). So then, in readANum, first check to see if there is anything to read; if not return an array of length 0. The method signature requires that an array be returned. (Arrays of length zero are perfectly legal, if usually really stupid because they cannot contain anything.) If the read is successful, put the thing read into an array and return that array. Finally, if something horribly wrong happens, and the catch occurs return an array of length 0, exactly as if there was nothing more to read.
The first thing you need to do is adapt the readANum method so that instead of reading one character as an integer, it reads 16 characters (as integers) and stores those 16 into an array. One challenge is that the integer you get from "fr.read()" is the ASCII value of the character. The ASCII value of the character '0' is NOT 0. But the ASCII value of '1' is one greater than the ASCII value of '0'. Similarly, the ASCII value of '2' is one greater than '1'. (etc)
Also there is one invisible character at the end of every line. So, when you read the 16 digits of a credit card, be sure to read one extra character (and throw it away).
To make your lives at little simpler, the data file is guaranteed to have 16 digits on each line. So you do not need to do any data validation on the input file.
Once you have your method for reading a single credit card number working correctly, adjust the main function so that it can read all of the credit card numbers in the file. (Use a loop.) The biggest challenge here will be recognizing in the main function that there are no more credit cards to be read. Suggestion, study the readANum method above; in particular what does it do when "fr" is not "ready"? You can use this idea to signal back to the main function that there are no more cards.
Printing
Write a method, "printCreditCard" that takes the credit card number as an argument and makes a nice looking representation. Given an array containing the digits in a credit card, for example:
[1, 2, 2, 4, 5, 4, 4, 2, 6, 5, 5, 2, 7, 2, 2, 6]
a "nice" representation might look like
1224 5442 6552 7226
Implementing Validation Checks
Now that your program is able to read a credit card number from a file and store the digits in an array, you can implement the methods that will perform the checks to determine whether the credit card number is valid.
The rules that we will use for a valid credit card number are as follows:
- Neither of the first two digits may be 0
- If the third digit is even, the fourth must be odd; if the third digit is odd, the fourth must be even
- The third digit must either be a zero, or equal to the sum of the ninth and tenth digits
- The sum of all digits must be evenly divisible by 4
- If you treat the first two digits as a two-digit number, and the last two digits as a two-digit number, their sum must be 100
Note that the rules above refer to a "1-based index", so that the "first" digit would be the one at array index #0 and so on.
Implement each of the five rules as a separate method:
- Each method must be declared as public and static
- The input to each method should be an int array
- The return value of each method should be a boolean indicating whether or not the values in the array conform to the rule
Be sure to use meaningful names when writing these methods!
Suggestion: implement and test one validation method at a time. Think about how you would do this before proceeding.
Then, write a public, static method called validateCreditCardNumber() that takes an int array as its parameter and returns true if all of the individual validation methods return true, and returns false if any of the individual validation methods returns false.
Last, modify your program's main() method so that, after calling readCreditCardNumber() and printCreditCardNumber() method as in Part 1, the main() method passes the array to validateCreditCardNumber() and prints "Valid" if the number is valid and "Invalid" otherwise. Be sure everything appears on the same line.
Here is the output of my program for the cc.txt data file
1224 5442 6552 7226 invalid
1234 5678 9012 3456 invalid
1111 2222 3333 4444 invalid
2505 1988 0544 2775 valid
2598 1988 1844 2775 valid
Submitting
Create a readme
Use VSC to create another file in your HW5 directory. This file should be named "Readme". The contents of this file should follow this sample.
You should have at least 3 files in your HW5 directory: Verify.java, cc.txt and Readme. (You might also have .class files.)
Submit
If you did this work on your own computer
You will first need to copy the files from you own computer to a lab computer. To do so, you can go into the lab as with HW2 or use ssh. Either way, you will need to create
HW5 directory within you CS113 directory on the Unix machines. Recall, the can be done with the following commands:
cd
cd CS113
mkdir HW6
Once you have made the HW6 directory in Unix, open a terminal on you own computer and in that terminal use "cd" to navigate to the directory containing your work for this assignment. Assuming you use the same directory structure on your own computer and in the lab, this process can be accomplished with the following commands
cd
cd CS113
cd HW6
Then use the scp command to copy each of the files you want to submit from your computer to the lab. For example:
scp Readme UNIX_NAME@goldengate.cs.brynmawr.edu:CS113/HW5/Readme
As always, when you read "UNIX_NAME" put in your UNIX user name. Also, with each scp command you will need to enter your UNIX password.
Actually submit
Open a terminal in UNIX (again, you can use SSH to do so from your laptop) and execute the following Unix commands (assuming you put HW6 directory into a CS113 directory in your home directory).
cd
cd CS113
/home/gtowell/bin/submit -c 113 -d HW6 -p 6
In response to the submit command you should see a series of messages ending with:
Submitting archive...
Submission complete! Submission timestamp is 2023-08-08-15-30-28-EDT.