Overview

Write a program that encrypts or decrypts the contents of a text file using a secret keyword. Additionally, your program should analyse the frequency of occurrence of each alphabetic character in the encrypted or decrypted file that is produced. The first part of the exercise uses a simple encryption strategy known as a monoalphabetic cipher, whilst the second part uses a more sophisticated strategy called the Vigenère cipher.

Text files

Your program will work with three types of input text files. The plaintext file (P) is the original English file before encryption, the cipher text file (C) is the encrypted file and the deciphered file (D) is the result of decrypting the cipher text file. If your program works then the P and D files will be identical!

The three files will have filenames of the form messageP.txt, messageC.txt and messageD.txt, where the root filename message can change.

All the text in the plaintext file must be in capitals. Any characters such as spaces and punctuation are not encrypted. This means that the cipher text contains the same number of words (and the same punctuation) as the original text, each with the same number of letters, (which would be a help for a code breaker).

Keyword

The keyword is a single word that is used to generate the monoalphabetic or Vigenère cipher. It must not contain any duplicate letters. It will be typed into the GUI. The letters must be in capitals.

Sample Input/Output

The following cipher text is produced by the Vigenère cipher:

Keyword: LEOPARD

Plaintext: THE MAN WHO MAKES NO MISTAKES DOES NOT USUALLY MAKE ANYTHING EDWARD JOHN PHELPS

Cipher Text: ELS BAE ZSS APKVV YS AXSKDVIG SOVV YSH JSLDWPM BABH LRMIHZQR IRLAIG USVC PYHWTG

Letter Frequencies

The second output file will contain a report based on the text file that is produced as a result of the relevant encryption / decryption operation (i.e., based on the text in the C or D file respectively). The name of this second output file will be identical to the root filename, but with the letter F appended (e.g., messageF.txt). The contents of this report will be a table consisting of, for each letter of the alphabet:

  • the letter itself;
  • the frequency (the number of times it occurs in the file);
  • the frequency percentage (the frequency divided by the total number of alphabetic characters in the file, given as a percentage), to 1 decimal point;
  • the percentage frequency of the letter shown for an average English language document (these values are provided for you);
  • the difference between the percentages in columns 3 and 4.

Finally the letter with the maximum frequency should be displayed, together with its frequency percentage. If several letters have the same frequency, only the last letter (i.e., the one furthest down in the alphabet) should be displayed. The objective of this report is to show how close the letter frequencies in the output file are to those in an average English language document; this provides some indication as to the strength of the encryption.

The numbers displayed in the report should be lined up in columns, as illustrated by the following sample report:

LETTER ANALYSIS

Letter Freq Freq% AvgFreq% Diff
A 34 7.6 8.2 -0.6
B 12 2.7 1.5 1.2
C 19 4.3 2.8 1.5
D 9 2.0 4.3 -2.3
E 55 12.4 12.7 -0.3
...
Y 16 3.6 2.0 1.6
Z 0 0.0 0.1 -0.1

The most frequent letter is E at 12.4%

(Note that it should not be necessary to read back in the text file that is produced as a result of the encryption / decryption operation in order to produce the letter frequencies report.)

The GUI

Code to display the GUI shown below at the start of the program is supplied for you in the CipherGUI class. The GUI functionality will be governed by this class. The GUI display is shown as follows: See image.

The textfields are used to enter the keyword and the name of the input text file. Since all filenames will end with “.txt”, this suffix can be omitted at this stage, and added within the code. Buttons are used to choose which style of cipher to use, i.e., monoalphabetic or Vigenère cipher. (Full details of the encryption and decryption mechanisms for each of these ciphers are given below.)

Program Functionality

When a button is clicked, the keyword should be checked to ensure that it is valid. That is, it should be non-empty, and should contain only upper-case letters of the alphabet with no repeated character. Similarly, the validity of the filename should be checked, ensuring that it ends with either ‘P’ or ‘C’ (remember that “.txt” should be omitted). If either the keyword or the filename is invalid, then an error message should be displayed using JOptionPane, and the relevant textfield should be cleared, allowing the user to try again.

Otherwise the program will proceed to the encryption phase (if a filename ending in ‘P’ is entered, signifying that the user wishes to encrypt a plaintext file) or the decryption phase (if a filename ending in ‘C’ is entered, signifying that the user wishes to decrypt a previously encrypted file) and produce the frequency analysis. Any input/output exceptions (such as file not found) should be caught and handled with a JOptionPane error message, allowing the user to re-enter the filename.

Encrypting and decrypting

To encrypt the text, a cipher must initially be created. There are two ciphers that can be used, both based on a keyword – a simple monoalphabetic cipher and the Vigenère cipher. The GUI contains two buttons, and the user chooses which cipher to use after having entered the keyword and the text file.

Initially you should create a program that only works with the monoalphabetic cipher, and then go on to the Vigenère cipher if you have time. In addition to normal program use, each cipher array should be printed to System.out so that you (and your tutor) can verify that it has been created correctly.

It is not expected that the program should make any check that, upon decrypting a file, the user enters the same keyword and type of cipher that was used in order to initially create the encrypted file.

The ciphers are now described in more detail:

The monoalphabetic cipher

This uses two parallel arrays. The first is an array containing the letters of the alphabet in order. In the encryption array, the letters of the alphabet are arranged starting with the keyword and followed by the remaining letters in reverse order. To encrypt a character, you can calculate the index position of the character within the normal alphabet on the top line, by subtracting the value ′A′ from the character. The encrypted character is then the one in the corresponding position (with the same index) in the lower array. To decrypt a character, it is necessary to search for the character in the lower encryption array to find the index, before obtaining the corresponding character from the array on the top line.

Example: here are the alphabetic and cipher arrays for the keyword ‘LEOPARD’:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
L E O P A R D Z Y X W V U T S Q N M K J I H G F C B

The following shows a line of plaintext and its corresponding encryption under the above monoalphabetic cipher:

JAVA STYLE GUIDELINES
XLHL KJCVA DIYPAVYTAK

The Vigenère cipher

This uses several different cipher text arrays, one for each letter in the keyword. Thus you will need an array of arrays (a 2D array) to store the different encryption arrays.

Each row of the encryption arrays starts with one letter of the keyword followed by the remaining letters of the alphabet in order, with A following Z. Thus there will be one encryption array for each letter in the keyword. You can assume that the keyword will not contain more than 26 letters!

Suppose the keyword is of length n. The first character to be encrypted is coded with reference to the first encryption array, the second using the second array, etc. The (n+1)th character uses the first encryption array again (because the keyword has only n letters), and so the cycle continues. Decryption uses a similar idea: the first character is decoded with reference to the first encryption array, and so on, cycling back to the first array when the (n+1)th character is reached.

Example: here are the alphabetic and cipher arrays for the keyword ‘TIGER’:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
R S T U V W X Y Z A B C D E F G H I J K L M N O P Q

The following shows a line of plaintext and its corresponding encryption under the above Vigenère cipher:

JAVA STYLE GUIDELINES
CIBE JMGRI XNQJICBVKW

Ending the program

The program should terminate after one encryption or decryption option.

Getting started

Launch Eclipse.

Create a new Java project called AE2 in your workspace. You must ensure that in the project creation wizard, you choose the option “use project folder as root for sources and class files”. If you find that folder AE2 has sub-folders src and bin, you have chosen the wrong option and should delete the project and create it again.

Download the zip file provided. Extract the files contained in the zip file into your folder H:workspaceProgAE2. These are AssEx2.java, CipherGUI.java, LetterFrequencies.java, MonoCipher.java and VCipher.java.

Only parts of the corresponding classes have been completed; the remaining code is to be written as part of this exercise.

Program Design

Your program should again follow the Model – View – Controller style. There will be a joint View/Controller class called CipherGUI, together with a main class to create it. There should be separate Model classes named MonoCipher, VCipher and LetterFrequencies. The first two model classes create and handle operations associated with a monalphabetic and Vigenère cipher respectively, whilst the third model class creates the letter frequencies report. These classes should not handle any user interaction.

The GUI (i.e., View/Controller) class should open the input and output files and read from / write to them, passing letters to the cipher objects and getting encrypted or decrypted letters back from them. Thus user interaction (the responsibility of the GUI) includes handling files as well as windows and GUI components.

The LetterFrequencies object should do its setting up in the constructor and then be given letters as the encryption or decryption takes place. You should then work out when the LetterFrequencies object should calculate the frequencies and how it should report the totals and frequencies for each letter, as well as the most frequent letter, to the GUI class.

Program Development

You should develop your program incrementally in small steps. When you have got one bit working, save a copy of the whole folder before continuing. Marks will not be given for sections of a program which are coded but do not work. Very few marks will be given for a program which does not compile. It should be possible to get a grade B for a good program that does not implement the Vigenère Cipher. Here is a suggested plan of attack:

  • Extend the program to read the input file. This will involve adding the .txt extension to the filename provided by the user and opening the file.
  • Create the MonoCipher class and create the monoalphabetic cipher in the constructor. Use System.out.println(…) within the constructor to print out the contents of the arrays to ensure that they are correct. Don’t carry on until you have got this bit right. Leave the System.out in for your tutor to check when marking!
  • Extend the MonoCipher class to contain the code for the method to return an encoded letter from a character parameter. Extending CipherGUI, read a very short input text file (a few words only, or even just one character if you like), encode each character and display the returned value/s using System.out.
  • Repeat with a longer text file, then output to text file.
  • Write the LetterFrequencies class and extend CipherGUI to accumulate letter frequencies and the total number of alphabetic characters. Use System.out to check the values in the frequency array are correct. Finally output to the text file.
  • Extend CipherGUI and the MonoCipher class to decode as well as encode.
  • Write the VCipher class for the Vigenère cipher and alter the GUI class to include code to react to the Vigenère button. Again use System.out to print out the contents of the encryption arrays.

Report

Write a short summary (no more than one page, excluding screen dumps) of the final state of your program in a Word file. It should indicate how closely your program matches the specification. There should be a statement detailing the inputs that you have used to test that the program is working correctly before submitting the final version. This statement should include a description of the results you would expect when executing the program with your data. The report should include:

  • Any assumptions you have made that have affected your implementation.
  • Any known deficiencies, e.g., missing functionality or discrepancies between your expected and actual results and how you might correct them. If your program does meet the specification all that is needed is ONE sentence stating this
  • Details of the test data used and the results expected and obtained should be provided, using screenshots as appropriate. Test data should include a plaintext file, its encrypted and decrypted versions, the letter frequencies file and the cipher arrays, in each of the cases of the monoalphabetic and the Vigenère ciphers. It should also include evidence of testing for incorrect input involving the keyword and message file name.
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.