COMP122 Assessment 1                                                                                                                 Due 2021-03-19 at 5pm


Le chiffre indéchiffrable

In this coursework you will implement a whole bunch of simple substitution ciphers in an object oriented fashion, as depicted in the (incomplete) UML diagram below. The interface Cipher is given as part of the exercise and should not be changed in any way.



Part 1: Subtitutions

Substitution ciphers de/encrypt one letter (or other small unit) at a time. Write an abstract class called Substitution that implements the given interface Cipher. It should do so by implementing the methods encrypt and decrypt that take and return strings, using two abstract methods by the same names but which take and return individual characters.

To be clear, this class should have two abstract methods,

which are left unimplemented, and two methods

that have concrete implementations. The first one should call the abstract encrypt method one character at a time and return the so constructed string, and similarly for the decrypt method.


Part 2: MonoAlphaSubstitution

Monoalphabetical substitution ciphers are ciphers that de/encrypt characters according to one fixed translation table (the alphabet). Your task is to write a concrete subclass of Substitution called MonoAlphaSubstitution that represents such ciphers. This of course means that you will have to overload the two abstract methods encrypt and decrypt above with concrete implementations.

How the translation table is stored internally is up to you but the class should offer at least two constructors:

1. a default constructor (one without arguments), which results in the trivial identity substitution (‘a’ → ‘a’, ‘b’ → ‘b’,... ) where every letter is mapped to itself.

2. a constructor that takes a String and interprets it as a mapping where every character at an odd position is the encoding of the one directly before it. The first character (at position 0) will be encryptd as the second (at position 1), the third as the fourth and so on. This way the string "ABBCCD", should be interpreted as ‘A’ → ‘B’, ‘B’ → ‘C’, ‘C’ → ‘D’ and every other letter to itself.

The methods encrypt and decrypt (that both take a char and return a char) should then be imple-mented so that they translate a plaintext character into its cryptotext variant (and back, respectively) according to the translation table set up in the constructor method.

Your class should have a main method, that allows to encrypt/decrypt text and accepts exactly three command line arguments, as follows.

1. "encrypt" or "decrypt", to indicate which direction you want to translate

2. The string defining the translation, as for the String constructor

3. the text to en/decrypt.

All user input must be read from command line arguments. Do not use Scanner or other means for getting user input! The only output printed by the program should be the output of the cipher. See below for example outputs. Your program needs to print the exact same output to be considered correct.


Part 3: Caesar

You know this one already from the first assignment. The Caesar cipher is a special case of a monoal-phabetical substitution, where each character maps to the one k position later in the alphabet, for a fixed shift k which is the secret key.

The task here is to write a subclass Caesar of MonoAlphaSubstitution. There should be at least a default constructor (leading to the identity again) and another constructor that takes an integer shift, according to which all en/decrypt methods operate.

Objects of type Caesar should be ciphers that translate both lower case and capital letters according to the shift specified at instantiation. Every other characters should be translated to itself.

Your class should have a main method that allows to encrypt/decrypt text, and that works similar to the one described for Substitution. See below for example outputs. Your program needs to print the exact same output to be considered correct.


Part 4: Vigenère

The Vigenère cipher is a 16th century encryption scheme first described by Giovan Battista Bellaso and later misattributed to French diplomat Blaise de Vigenère. It addresses the main weakness of earlier ciphers which are easily broken with a frequency analysis.

The idea behind the Vigenère cipher is to disguise the plaintext letter frequencies by not encoding each letter according to the same translation table. Instead, it uses one translation table for each letter position in the plaintext. Such ciphers are called polyalphabetic substitutions because there is more than one mapping (alphabet) involved. This way, the most common letter ‘e’ for instance translates to different letters depending on where in the plaintext it occurs. In fact this cipher has resisted crypto-analytic attacks for well over two centuries, which earned it the nick name le chiffre indéchiffrable.

What makes this cipher particularly user friendly is the way one specifies the secret key, i.e. the substi-tutions to use at each position. This is done by arranging several Caesar ciphers with different shifts based on some key word which is easy to remember for all communicating parties.

Suppose for example that the keyword is “COMPONETWOTWO”. Then the first character of the plaintext would be translated according to a Caesar cipher with shift 2, as 'C'- 'A'== 2, the first letter ‘C’ of the keyword is two letters after ‘A’ in the Roman alphabet. The second character will be translated using a Caesar cipher with shift 14 == 'O'- 'A' and so on. If the plaintext is longer than the key one continues at the start of the key word, so that the 14th position will again use the Caesar shift 2. If you encrypt the phrase “fun fun fun” with the key above, you should get “hiz thr big”. Notice that the letter ‘f’ maps to a different letter each time!

Your task is to implement this cipher in a class called Vigenere which should be a concrete subclass of Substitution (after all, this is still a character-by-character encoding scheme). This means that again, you will have to overload the abstract methods encrypt and decrypt with char-parameter with concrete implementations but now consecutive calls to the same method may give different results, so you will need to store the position your are at somehow in the object. You may freely use all other classes that you have written.

The Vigenere class should again have at least two constructors:

• a default constructor (no arguments), which results in the identity as before

• one that takes a single String argument, the key word used in the cipher.

You may assume that the key word consists only of capital letters without spaces or punctuation.

Your class should have a main method that allows to encrypt/decrypt text, and that works similar to the ones described above. See below for example outputs. Your program needs to print the exact same output to be considered correct.


Hints

1. the String methods toCharArray and charAt may be useful.

2. For Vigenere, I would recommend you use an array of Ciphers to keep around several Caesar objects.

3. In all parts, it is perfectly fine to re-use your own code or helper methods from the Java standard library. It is also fine to add your own helper methods to any of the classes in addition to what the exercise requires.

4. Do not use Scanner or any other means to read user input. All input should be read from command line arguments only!


Submission

Submit you solution using submit50 just like the lab exercises.

To check that your submission is in the correct format you can run check50 on the same slug.


Fine Print

Submissions are subject to UoL’s Code of Practice on Assessment and the usual late penalties apply. This means you can still submit until 120 hours past the deadline, and will incur a -5% penalty for each 24 hour period immediately following the deadline. Submissions after that will not be considered. You can submit multiple times and only the latest version (and it’s submission time) will be used for grading.

If you require an extension due to extenuating circumstances please get in touch with the CS student office ([email protected]) before the submission deadline. We will not grant any extensions afterwards. If you are granted an extension you cannot in addition submit late after your personal deadline.

The results will be made available on Canvas and we aim for a turn-around time of three weeks.