Convert all letters in the string to lowercase.
Step 6 Input Line: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Step 6 Output Line: "abcdefghijklmnopqrstuvwxyz"
Below gives an example of applying all six steps sequentially:
Example 2:
Encryption Input Line: "LM#Q&$+U^W%@BYZCD=FGH!?KN*"
Encryption Output Line: "abcdefghijklmnopqrstuvwxyz"
The Output File
The output file is named "decrypt.txt". An output file, which corresponds
to the above input and intermediate files, is shown below.
abcdefghijklmnopqrstuvwxyz
The files for this encryption/decryption sample will be available on the course web site.
You can use this sample (as well as others of your own devising) as an input source in
your own test cases by creating a BufferedReader attached to the message.txt URL.
Note, however, that it is not sufficient to do your testing only using this sample--you
must create additional tests using your own input (see the hints on testing your solution below).
Solution Requirements
- You must provide a class called "Cipher" to serve as the main entry
point for your solution.
- Your Cipher class must provide a method with the following signature:
public void encrypt( BufferedReader inStream,
PrintWriter outStream )
throws Exception
{
// ...
}
- The Cipher.encrypt() method must correctly translate all of the input characters
from the provided message inStream, and produce the corresponding encrypted output
on outStream.
- Your Cipher class must also provide a method with the following signature:
public void decrypt( BufferedReader inStream,
PrintWriter outStream )
throws Exception
{
// ...
}
- The Cipher.decrypt() method must correctly translate all of the input
characters from the provided encrypted message inStream, and produce the
corresponding decrypted output on outStream.
- The Cipher.encrypt() and Cipher.decrypt() methods must not
throw any exceptions, except for those that arise from calls sent to inStream.
The Cipher class is only responsible for storing data for the cipher technique
described in this project. Behavior for handling other cipher techniques must
NOT be included in the Cipher class.
Implementation Hints
You are encouraged to design your solution piecemeal. Begin by identifying the major
tasks that have to be done, and then add detail for each of those tasks. Your
implementation should be developed in the same manner. A good starting point for
this assignment is the stepwise implementation of the previous program. Apply a
similar strategy to the decryption process for this program. Remember that by
decomposing the problem you allow yourself to focus on solving a single part of the
problem at any one time. You will find that this will greatly increase your odds of
producing a correct solution.
Review the brief tutorial on Files and Stream-based
Input and Output. Make sure you understand the basic methods
described in it.
The most direct strategy for implementing a solution is to
read from the input stream one character at a time, processing each
character appropriately. Characters that represent a replacement
characters can be substituted by their corresponding encrypted/decrypted,
character and all other
characters can be echoed unchanged to the destination.
You may also wish to look carefully at the "one character at a time"
file copying example in the stream I/O tutorial.
Remembering a Sequence of Characters
Another issue that may come up is how one can "remember" a sequence
of characters, so that they can be used again later. One thing
that you can do is append a character onto the end of an existing
character string:
String oldCharacters = "";
...
int myChar = in.read();
...
// To "save" characters that have been read before, "add" them
// onto the end of a string:
oldCharacters = oldCharacters + (char)myChar;
...
// see what has been saved up
System.out.println( oldCharacters );
...
// Clear it out to start over
oldCharacters = "";
Note that both of these hints use the funny notation
"(char)myChar
". This is called a type cast,
and instructs Java to treat the number stored in myChar
as the code for a single character, rather than as a plain number.
If we didn't do that, Java would add a human-readable decimal representation
of the number stored in myChar
to
oldCharacters
, rather than adding the character
whose code is stored in myChar
.
Testing Hints
When it comes to testing, remember to write one or more test cases for each method
that your write in your solution. Preferably, you should write these tests before
(or as) you write the method itself, rather than saving testing until your code
works. As you work on larger and larger programs, it is important to build skills
in convincing yourself that the parts you have already written work as you intend,
even if the full solution has not been completed.
Also, In addition to trying to think of various cases that your
methods should add formatting to, also write test cases for scenarios
where a method should not take action (or should signal an error
condition, if that is the behavior intended).
Finally, be sure to review the section on Reading
from and Writing to Strings in the stream I/O tutorial. By using
one string as an input stream, and then generating output in another
string, it can be very easy to write short test cases. Consider
the following test method (which assumes your text fixture includes
a p4Cipher
object created from your
Cipher
class):
public void testEncryption()
{
try
{
// create the streams needed
BufferedReader inStream =
IOHelper.createBufferedReaderForString(
"abcdefghijklmnopqrstuvwxyz" );
StringWriter result = new StringWriter();
PrintWriter outStream = new PrintWriter( result );
// run the method to get results
p4Cipher.encrypt( inStream, outStream );
inStream.close();
outStream.close();
// test that the result is what was expected
assertEquals( result.toString(),
"LM#Q&$+U^W%@BYZCD=FGH!?KN*" );
}
catch ( Exception e )
{
// If this happens, something went wrong;
fail(); // treat as a failed test
}
}
If you are clever, you can even create a "helper" method in your
test class that takes two strings, the input string and the
expected output string, and carries out the above test. That way,
you can write many test cases, each of which is performed simply
by calling your "helper" to do all the work. Even when writing
test cases, it is a good idea to try to capture repeated code
sequences in reusable pieces (placing them in their own methods,
for example).
Submit Your Solution
Program submissions work just like lab submissions.
On BlueJ's main menu, click Tools->Submit...
. Click on
"Browse...
", double-click to open the
"CS 1054 Programs
" folder, and select
Program 4
. Click "OK
".
Click "Submit
". Click on the link provided
in the submission response in order to view the results of the
automated phase of program grading.
If no "Program 4" entry is visible on BlueJ's submission menu, then
the Web-CAT Grader is not yet accepting submissions for this assignment.
Wait for a message posted to the course web site that submissions are
being accepted, and try again.
If any errors, warnings or suggestions are indicated, you can fix them
and resubmit. You are expected to fix all such issues in your
code. You
may resubmit as many times as you like, up until the deadline.
Be careful as the due time approaches--if you submit just over the
deadline, a late penalty will be assessed.