CS 124, Spring 2013
Lab 8: Vigenère Cipher

Once again this week, you will be working with subroutines. In this case, you will work on an implementation of the Vigenère Cipher, the system for encoding and decoding text messages that was discussed and demonstrated in class. This is an exercise in writing subroutines and in using an API that provides some utility functions that can be used in solving the problem.

You should create an Eclipse project named lab8. You will need copies of the files CodeUtil.java and TextIO.java; You should copy them from /classes/cs124 into your project's src folder.

This lab is due at the beginning of Lab 9 (which is two weeks from today because of Spring Break). To turn in the lab, you can copy your project folder into your homework folder in /classes/cs124. (Alternatively, you can just turn in the Java files that are need to run your program; put them in a folder named lab8.)

The Assignment

You should write a program that does encoding and decoding of messages using the Vigenère cipher. For the main() routine in your program, you should use the following code, which you can copy-and-paste into your program:

public static void main(String[] args) {
    
    String plainText;   // The un-encrypted message.
    String cipherText;  // The encrypted message.
    String key;         // The key for the Vigenere cipher.
    boolean encodeFlag; // Whether to do encoding or decoding.
    
    key = readVignereKey();  // returns a string of letters only!
    encodeFlag = askUserEncodeOrDecode();

    if (encodeFlag) {
        plainText = readInput();
        plainText = CodeUtil.lettersOnly(plainText);
        cipherText = vigenereEncode(plainText,key);
        writeOutput(cipherText);
    }
    else {
        cipherText = readInput();
        cipherText = CodeUtil.lettersOnly(cipherText);
        plainText = vigenereDecode(cipherText,key);
        writeOutput(plainText);
    }

} // end main();

To finish the assignment, you should write all the subroutines that are required by this main() routine. This includes writing a Javadoc comment for each subroutine. Here are the requirements for the subroutines:

You should use functions from CodeUtil.java when appropriate. Read that file to see what functions are available.

Here is an example ciphertext that was encoded using the key carpe diem. This is an encoding of the preamble to the U.S. constitution: "We the people of the United States, in order...". Your program should be able to decode it:

YEKWISMSBNEFUXKMYZKTVSWWIXQUIEDVGMVFQFFGQDUSDGPVGJHKXGPIFCIV
BENNIJWNXAXUEEZCWXZIPQMVHXLKXDCNHJMOQXKRRFKMGMJATTYTGRUQAPDV
UIQKIBTODDXHBLQIEETVDTAQNFRGIDVHEGCLGIWPINNEJHMQOWAHLZQIUBCF
QOLGWHTZQUAESSXZTAUTVGMWGHAQRUPMQIRPGSKPFOQWTVHZHGRVWFKTLIMR
VJATTYTYQQXQFSKPXHASRCMVGMFI

The StringBuffer Class

There are several points in the Vigenere program where you will have to create a potentially long string by combining shorter strings or individual characters. This coul be done using the "+" operation to combine the strings, but that can be inefficient if you do it a lot, since a new copy of the entire string is created each time you add something to the string. Java has a standard class named StringBuffer that is much more efficient for building lots of strings. You should use it in your program.

An example of using StringBuffer is in the lettersOnly method in CodeUtil.java. This example shows the typical use of a StringBuffer:

public static String lettersOnly(String str) {
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);
        if ( ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' )
            buffer.append(ch);
    }
    return buffer.toString();
}

You can compare this to performing the same task using "+":

    String str = "";
    for (int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);
        if ( ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' )
            str = str + ch;
    }
    return str;

A StringBuffer builds up a string internally, using an append() method instead of "+". The lettersOnly subroutine creates a StringBuffer named buffer, adds characters to the buffer by calling buffer.append(), and gets the string that was created inside the buffer by calling buffer.toString(). Note that buffer.append() can be used to add strings and other types of data to the buffer, as well as characters.

Style Rules For Subroutines

Here are a few new style rules, relevant to writing subroutines and using member variables. You are expected to follow these rules, starting with Project 8.

Note that Javadoc comments are covered in the textbook in Section 4.5.4 Be sure to read that section and make sure that you understand how to write Javadoc and what it is for.