Project 1A: (Slightly) Better Encryption

For this assignment, you will re-write your Ceasar Cipher program from the beginning of the semester. Instead of a straight rotation of letters, you will implement a substitution cipher. You may want to go back and review the chapter, Secret Bits, that we read during the first week. In a subsequent part of this project, you will write code that cracks such codes using frequency analysis.

Implementation guidelines

As you review substitution ciphers, keep in mind that Caesar ciphers are a special case of the general class of substitution ciphers. For the substitution cipher portion of this assignment, you may implement any of the general class of substitution ciphers based on a fixed permutation of our alphabet.


The requirements for this assignment are quite modest; consequently, the due date is less than one full week. We are doing this in order to give you more time on other parts of the project that will probably prove to be more challenging.

  1. Review Substitution Ciphers. For our next foray into encryption and code breaking, we will focus on an old method known as substitution ciphers. Such codes are only slightly better than Ceasar ciphers that we implemented previously. I recommend that you review Secret Bits: How codes became unbreakable, by Hal Abelson, Ken Ledeen and Harry Lewis. For this assignment, only the first part of the chapter is relevant.
  2. Write a simple substitution cipher. Write a class, SubstitutionCipher, that supports the following functionality:
    1. constructors. Your class should have a default constructor that generates a random substitution key. You should also provide a constructor that consumes a String argument that has 29 characters and represent the key to use for encrypting and decoding arbitrary messages. Interpret the 29 characters in the given key as establishing the mapping for our three punctuation characters -- space, question-mark, and period (in that order) -- followed by the 26 letters of the alphabet (in normal order). Note: the space is being treated just like the other characters and so one cannot discern the number of letters in an encrypted word without assuming an encoding for the space.
    2. encryption. Implement a public method public String encode(String plainText) that converts the given plainText String into an encrypted string. Lower-case letters should be converted to upper-case. Characters other than the 29 we support should be dropped.
    3. decode. Implement a public method public String decode(String cipherText) that takes a given encrypted String and decodes it using the key that was either specified or generated when the constructor was called. Also write a static method public static String decode(String cipherText, String key) that decodes the encrypted text using the given key. Note: you must avoid the duplication of code.
  3. Putting it all together. Write a main method that will do one of two things. If there is a single command-line argument the program should treat the argument as a filename, encrypt the contents of the file, and display both the encrypted result as well as the key that was used to do so. If there are two command-line arguments, the program should treat the first as the filename of a cipher text and the second argument as the key string. In this case, your program should decrypt the cipher text and display the plain text message.

Submission Instructions:

On your machine where you are doing your homework, create a folder called <your email name> followed by “P01A”. For example, someone with email address “cjones” would create a folder called “cjonesP01A”. Inside that folder, place whatever Java and documentation files are necessary for your programming project. Finally, either tar or zip the folder so that when I extract it, the folder ”<emailname>P01A“ will be created. Finally, submit via Eureka.