p3-ciphers

EECS 183 Project 3: Ciphers

Due Friday, October 18th at 8:00 p.m. (accepted until 11:59:59 p.m.)

Overview

In this project, you will move on to cryptography and you’ll be asked to encrypt and decrypt messages using three different encryption algorithms. The S’more part of this project will challenge you to “crack” others’ secret messages in ciphertext and convert them back to plaintext.

Objectives

WARNING: Beware the autograder’s ability to detect cheating, see Honor Code for further information.

Honor Code

Collaboration Policy and the Honor Code

You are encouraged to:

To clarify the last item, you are permitted to look at another student’s code to help them understand what is going on with their code. You are not allowed to tell them what to write for their code, and you are not allowed to copy their work to use in your own solution. If you are at all unsure whether your collaboration is allowed, please contact the course staff via the admin form before you do anything. We will help you determine if what you’re thinking of doing is in the spirit of collaboration for EECS 183.

The following are considered Honor Code violations:

The full collaboration policy can be found in the syllabus.

Grading

Submission Rules

Remember that we grade your BEST submission for style. If multiple submissions are tied in score, we take the last of those.

Working with a Partner

Starter Files

Download the starter files using this link. After unzipping, you’ll find these files:

utility.h A header file with declarations (aka prototypes) of the helper functions you’ll have to implement.

utility.cpp Implementations of functions declared in utility.h.

caesar.h A header file with declarations of the functions related to caesar cipher you’ll have to implement.

caesar.cpp Implementations of functions declared in caesar.h.

vigenere.h A header file with declarations of the functions related to vigenere cipher you’ll have to implement.

vigenere.cpp Implementations of functions declared in vigenere.h.

polybius.h A header file with declarations of the functions related to polybius cipher you’ll have to implement.

polybius.cpp Implementations of functions declared in polybius.h.

ciphers.cpp A function that allows the user to encrypt and decrypt messages. This file uses functions from utility.h, caesar.h, vigenere.h, polybius.h.

start.cpp A program that allows you to select between executing your tests in test.cpp and using the ciphers you have created.

Additionally, you’ll be working with this file that you’ll have to create yourself:

test.cpp A test suite for functions declared in utility.h, caesar.h, vigenere.h, polybius.h. Its job is to reveal bugs that someone (e.g. you or staff) could have made while implementing those functions. All testing should be done by printing to the standard output. Note that there will be no main function in this file.

NOTE: The starter code will not compile until you:

Suggested Timeline

As an approximate timeline, you will be on track if by:

Warm-up

To make working on this project easier and more fun, be sure you’re able to answer the following questions:

Getting Started

Multiple Files

Creating a Project

-------------------------------
EECS 183 Project 3 Menu Options
-------------------------------
1) Execute testing functions in test.cpp
2) Execute ciphers() function to use ciphers
Choice --> 1

Executing your test case
Now testing function toUpperCase()
Expected: "HELLO WORLD!", Actual: "HELLO WORLD!"
Expected: "HI THERE 123", Actual: "HI THERE 123"
Expected: "&&GO BLUE**", Actual: "&&GO BLUE**"

Test Suite

Creating test.cpp

List of Functions to Test

Here the a list of functions you will need to test in test.cpp.

Submit Frequently

Bugs To Expose

There are a total of 13 unique bugs to find in our implementations. Your tests do not need to expose all of the bugs to receive full points for the project. The autograder will tell you the names of the bugs that you have exposed, from the following set:

Helper functions

After your code compiles, your next task in this project is to indulge in writing functions in utility.cpp. These functions will serve as helper functions in caesar.cpp, vigenere.cpp, and polybius.cpp Remember to write your testing function for each function before you write the function itself. For example, write test_toUppercase() (in test.cpp) before you write the implementation of toUpperCase().

toUpperCase()

string toUpperCase(string original);

removeNonAlphas()

string removeNonAlphas(string original);

removeDuplicate()

string removeDuplicate(string original);

charToInt()

int charToInt(char original);

cctype Library Functions

You are allowed and encouraged to use functions from the cctype library shown in the Character operations section in zyBooks.

WARNING: Do not compare boolean values to true or false in a conditional expression.

When using these functions, the note below the table is critical in understanding how to use the functions like isalpha, isdigit, and isspace. As noted in zyBooks, for functions like isalpha, false is zero and true is non-zero.

This means you must never do the following:

if (isalpha(someCharVariable) == true)

Instead you should do something like this:

if (isalpha(someCharVariable))

to_string Function

You may find the function to_string helpful in this project. The function takes as input an integer (it also works for double but that is not relevant for this project), and returns a string with characters of text representation of the integer input. Note this does not work to convert a char to a string.

// Example: converting an integer to a string using to_string
int course = 183;

// string word will have the value "183"
string word = to_string(course);

// prints 183
cout << word << endl;

Ciphers

IMPORTANT: As you implement the functions in the next section, you will find it helpful to refer to the Function Table linked at the bottom of the spec. The table contains the relationship between the functions below, i.e., which functions are called by others.

Art of Cryptography

caesar.cpp

Cæsar

NOTE: Most of this project’s specification has been encrypted with a key of 26, which is twice as secure as a key of 13.[1]

shiftAlphaCharacter()

char shiftAlphaCharacter(char c, int n);

caesarCipher()

string caesarCipher(string original, int key, bool encrypt);

IMPORTANT: Don’t forget to keep writing tests in test.cpp for functions we declared in caesar.h!

For creating and verifying test cases for your caesarCipher, this website may be helpful.

vigenere.cpp

Vigenère

vigenereCipher()

string vigenereCipher(string original, string keyword, bool encrypt);

polybius.cpp

Polybius Square

grid decrypt

IMPORTANT: Note that the grid does not represent any non-alphanumerical character. This means that such characters cannot be encrypted. However spaces are allowed in the plaintext, and should be represented as spaces in the ciphertext.

fillGrid()

void fillGrid(char grid[SIZE][SIZE], string content);

mixKey()

string mixKey(string key);

findInGrid()

string findInGrid(char c, char grid[SIZE][SIZE]);

polybiusSquare()

string polybiusSquare(char grid[SIZE][SIZE], string key, string original, bool encrypt);

IMPORTANT: Note that spaces are allowed in the original message, and they must stay as spaces in the encrypted message as well.

ciphers.cpp

WARNING: Sanity check! At this point, utility.cpp, caesar.cpp, vigenere.cpp, and polybius.cpp should have implementations of all functions that we declared in utility.h, caesar.h, vigenere.h, and polybius.h, and test.cpp should have a test suite for those functions. If you have not yet submitted, we highly encourage you to do so, unless you are starting late and it is close to the deadline so you have few submissions remaining.

Overview

WARNING: Be sure not to modify any of the header files, since we’ll be using the original version when grading your project.

Error handling in ciphers()

WARNING: This section applies to the ciphers() function in ciphers.cpp. These are not instructions for how to implement each cipher - caesar, vigenere, or polybius. These are instructions for how to handle user input within the ciphers() function so that your ciphers.cpp does not violate the Requires clause of the RMEs for your caesarCipher, vigenereCipher, and polybiusSquare functions.

Your ciphers() function must not violate the Requires clause of the RME for any functiuon. Since the user may enter values that may do so, you must catch these and either print an error message, or modify the input values to conform to the Requires clause before calling the corresponding cipher function.

Here are the errors you must handle in ciphers():

Sample Output

When you run ciphers.cpp, it should behave per the examples below. Assume that the red underlined text is what some user has typed.

NOTE: The following sample runs do not include the menu selection detailed in Creating a Project.

Sample Run 1

Choose a cipher (Caesar, Vigenere, or Polybius): caesar
Encrypt or decrypt: encrypt
Enter a message: I solemnly swear that I am up to no good.
What is your key: 7
The encrypted message is: P zvsltusf zdlhy aoha P ht bw av uv nvvk.

Sample Run 2

Choose a cipher (Caesar, Vigenere, or Polybius): c
Encrypt or decrypt: d
Enter a message: P zvsltusf zdlhy aoha P ht bw av uv nvvk.
What is your key: 7
The decrypted message is: I solemnly swear that I am up to no good.

Sample Run 3

Choose a cipher (Caesar, Vigenere, or Polybius): vigenere
Encrypt or decrypt: decrypt
Enter a message: U lgp'a os qaoxitk iaz ltvcfqq. Teoafoq ckwhtpd riady qh.
What is your key: Mischief managed.
The decrypted message is: I don't go looking for trouble. Trouble usually finds me.

Sample Run 4

Choose a cipher (Caesar, Vigenere, or Polybius): ViGenere
Encrypt or decrypt: DECrypt
Enter a message: U lgp'a os qaoxitk iaz ltvcfqq. Teoafoq ckwhtpd riady qh.
What is your key: Mischief managed.
The decrypted message is: I don't go looking for trouble. Trouble usually finds me.

Sample Run 5

Choose a cipher (Caesar, Vigenere, or Polybius): polybius
Encrypt or decrypt: encrypt
Enter a message: EECS 183 is the best
What is your key: POLYBIUS
The encrypted message is: 15151311 435445 0511 332215 04151133

Sample Run 6

Choose a cipher (Caesar, Vigenere, or Polybius): P
Encrypt or decrypt: E
Enter a message: EECS 183 is the best
What is your key: polybius
The encrypted message is: 15151311 435445 0511 332215 04151133

Sample Run 7

Choose a cipher (Caesar, Vigenere, or Polybius): hello
Invalid cipher!

Sample Run 8

Choose a cipher (Caesar, Vigenere, or Polybius): C
Encrypt or decrypt: V
Invalid mode!

Sample Run 9

Choose a cipher (Caesar, Vigenere, or Polybius): v
Encrypt or decrypt: e
Enter a message: EECS 183 is the best
What is your key: 183
Invalid key!

Sample Run 10

Choose a cipher (Caesar, Vigenere, or Polybius): P
Encrypt or decrypt: enCRYPT
Enter a message: Life isn't about waiting for the storm to pass its about learning to dance in the rain
Invalid message!

Sample Run 11

Choose a cipher (Caesar, Vigenere, or Polybius): PolyBius
Encrypt or decrypt: EnCrypt
Enter a message: The grasshopper lies heavy
What is your key: YEET!!!
Invalid key!

Sample Run 12

Choose a cipher (Caesar, Vigenere, or Polybius): Polybius
Encrypt or decrypt: Encrypt
Enter a message: The grasshopper lies heavy
What is your key: 183EECS
The encrypted message is: 341503 1433100505153031310333 23200305 1503104043

Sample Run 13

Choose a cipher (Caesar, Vigenere, or Polybius): Polybius
Encrypt or decrypt: decrypt
Enter a message: 341503 1433100505153031310333 23200305 1503104043
What is your key: 183EECS
The decrypted message is: THE GRASSHOPPER LIES HEAVY

Sample Run 14

Choose a cipher (Caesar, Vigenere, or Polybius): Caesar
Encrypt or decrypt: encrypt
Enter a message: Do androids dream of electric sheep?
What is your key: 9000
The encrypted message is: Hs erhvsmhw hvieq sj ipigxvmg wliit?

IMPORTANT: Note that when selecting Polybius Square, the decrypted message is all uppercase, while the original message contained lower case letters. This is fine, as the grid we construct only supports uppercase letters.

Function Table

WARNING: The table below does not include all cases of where to use the helper functions from utility.cpp. There are hints in the specification where to use your helper functions, and you should consider implementing these functions first.

File Function Other functions it should call
utility.cpp toUpperCase() Does not utilize any other functions
utility.cpp removeNonAlphas() Does not utilize any other functions
utility.cpp charToInt() Does not utilize any other functions
utility.cpp removeDuplicate() Does not utilize any other functions
caesar.cpp shiftAlphaCharacter() Does not utilize any other functions
caesar.cpp caesarCipher() shiftAlphaCharacter()
vigenere.cpp vigenereCipher() toUpperCase(), removeNonAlphas(), shiftAlphaCharacter()
polybius.cpp mixKey() removeDuplicate()
polybius.cpp fillGrid() Does not utilize any other functions
polybius.cpp findInGrid() Does not utilize any other functions
polybius.cpp polybiusSquare() mixKey(), fillGrid(), findInGrid(), charToInt()

Here is an example of how to read the table:

NOTE: Note that the functions under “Other functions it should call” only refer to the functions you will implement. Feel free to use library functions anywhere.

Style Checklist

To maximize your style points, be sure to follow this non-exhaustive checklist:

NOTE: We will not be grading style in test.cpp.

How to Submit

IMPORTANT:

S’More Functionality

OPTIONAL: For more practice and fun, check out the S’More for Project 3. With this optional challenge you can implement the functions in decrypt.cpp to break encryption.

[1] http://www.urbandictionary.com/define.php?term=ROT26

[2] http://www.independent.co.uk/life-style/history/42-the-answer-to-life-the-universe-and-everything-2205734.html