1. Homepage
  2. Programming
  3. EECS 183 Elementary Programming Concepts - Project 3: Ciphers

EECS 183 Elementary Programming Concepts - Project 3: Ciphers

Engage in a Conversation
MichiganEECS183Elementary Programming ConceptsCiphersC++Encryption AlgorithmCryptographyPolybius Square

EECS 183 Project 3: Ciphers

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. CourseNana.COM

You are encouraged to:

  • Give or receive help in understanding course concepts covered in lecture or lab.
  • Practice and study with other students to prepare for assessments or exams.
  • Consult with other students to better understand project specifications.
  • Discuss general design principles or ideas as they relate to projects.
  • Help others understand compiler errors or how to debug parts of their code.

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. CourseNana.COM

Grading

  • 10 points testing. Write a test suite in test.cpp. CourseNana.COM

  • 60 points correctness. To what extent does your code implement the features required by our specification? To what extent is your code consistent with our specifications and free of bugs? CourseNana.COM

  • 10 points style. To what extent is your code written well? To what extent is your code readable? Consult EECS 183 Style Guide and check the Style Checklist at the end of this project’s specification for some tips! CourseNana.COM

  • If your last submission is on Wednesday, October 16th you will receive a 5% bonus on your autograder score. If your last submission is on Thursday, October 17th, you will receive a 2.5% bonus. CourseNana.COM

Submission Rules

  • You get 4 submissions to the autograder per day, with feedback. Beyond that, you get one additinal “bonus” submission per autograder, meaning that you get one extra submission with feedback, one time during the project period.

Starter Files
CourseNana.COM

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

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

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

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

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

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

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

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

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

ciphers.cpp A function that allows the user to encrypt and decrypt messages. This file uses functions from utility.hcaesar.hvigenere.hpolybius.h. CourseNana.COM

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

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

test.cpp A test suite for functions declared in utility.hcaesar.hvigenere.hpolybius.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. CourseNana.COM

NOTE: The starter code will not compile until you: CourseNana.COM

  • Create a test.cpp file with a function named startTests(). Your project will not compile until you have created your test.cpp. More details can be found in the section Creating test.cpp.

Suggested Timeline

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

  • September 30: Starter code downloaded and new project set up in IDE. All necessary file(s) created. Code compiles on your IDE. Code compiles on the autograder (submit to verify). You’ve read through the spec.
  • October 4: Functions in utility.cpp implemented, fully tested, and passed on the autograder. Associated testing functions in test.cpp implemented, working, and catching the associated bugs on the autograder. Suggested order: toUpperCase()removeNonAlphas()charToInt()removeDuplicate().
  • October 9: Functions in caesar.cpp implemented, fully tested, and passed on the autograder. Associated testing functions in test.cpp implemented, working, and catching the associated bugs on the autograder. Necessary order: shiftAlphaCharacter()caesarCipher()
  • October 11: vigenereCipher() implemented, fully tested, and passed on the autograder. Associated testing function in test.cpp implemented, working, and catching the associated bug(s) on the autograder.
  • October 14: Functions in polybius.cpp implemented, fully tested, and passed on the autograder. Associated testing functions in test.cpp implemented, working, and catching the associated bugs on the autograder. Suggested order: mixKey()fillGrid()findInGrid()polybiusSquare(). Began working on ciphers().
  • October 15: ciphers() and all other code should be completed. Debugging in progress. Passing all individual function tests, 80% or higher on autograder.
  • October 16: Last day to still get 5% extra credit for your project 3 submission!
  • October 18: Final due.
  • If at any point your code is not working as intended checkout the troubleshooting checklist

Warm-up

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

  • Recall our friend modulo, %. What does it do?
  • What’s the difference between a char and a string?
  • How can you figure out the length of a given string?
  • Suppose you have a variable of type string called word, and that word is of some positive length.
    • Without knowing word’s length in advance, how could you print its first character?
    • How about the last character?
    • How would you print word’s nth character?
  • How can you represent an empty string, i.e. a string of length 0?
  • Suppose you somehow ended up with this code: CourseNana.COM

    string firstName = "Julius";
    string lastName = "Caesar";
    // ...

    and that you’d like to have another stringfullName that would join (i.e. concatenate) firstName and lastName, so as to get "Julius Caesar". How best to do this? CourseNana.COM

  • Surf on over to http://www.asciitable.com and make note of Dec and Char columns.
    • Recall from lecture that characters, such as letters, punctuation marks and digits are represented by a number in the computer. So to store the character A, the computer is really storing the number 65. Similarly it stores 97 to represent a. Because of this property, you can increment chars and do arithmetic with them just like you can with ints.
      • Note You should never refer to ASCII values when working with chars. Instead, always use the alphanumeric or symbol representation. For example
      // do NOT use numerical ASCII values in your code, like below
      char ch = 65;
      if (ch == 66) {
      ....
      }
      // Instead, use the alphanumeric representation, like below
      char ch = 'A';
      if (ch == 'B') {
      ....
      }
    • What is the value of character at the end of this code’s execution? CourseNana.COM

      char character = 'A';
      character += 1;
      character += 'A' - 'a';
    • How would you print all the letters in the alphabet, A through Z, with just a couple lines of code (without hardcoding all those letters)?
  • What’s the difference between 0 and '0'?
  • How can you determine if a character is a lowercase letter?
  • How can you determine if a character is an uppercase letter?
  • How can you determine if a character is alphanumeric or alphabetical?

Getting Started

Multiple Files

  • Most programs in the real world are written in more than just one file, to break down the functionality into smaller parts and to keep the program’s organization clean. CourseNana.COM

  • For Projects 1 and 2, you worked with just one file, such as rps.cpp. It had a main() function, where the execution began, and then some other functions that were called from main() or from other functions. But as a program gets more complicated, the file becomes longer and it becomes difficult to organize and test the program. CourseNana.COM

  • And so a common practice is to put (at least some) functions into separate files. The functions’ declarations (aka prototypes) go in what’s known as a header files that end in .h and the functions’ definitions (aka implementations) go in .cpp files. Each .cpp file that implements functions will #include its respective .h file that contains the functions’ declarations. CourseNana.COM

    Then the program will contain one other .cpp file (without a header file) that will contain a main function that drives the program. This .cpp file will #include any header files that contain the definition of any functions that it might need. CourseNana.COM

Creating a Project

  • In the Distribution Code you’ll find utility.hcaesar.hvigenere.h, and polybius.h that has declarations for some functions. You’ll also find caesar.cppvigenere.cpppolybius.cpp, and utility.cpp whose job is to implement those functions. You will also find ciphers.cpp which is the driver that makes use of the ciphers you have implemented. Finally, there is a file start.cpp which contains the main() function for the project. This function will allow you to select executing your test cases or using the ciphers you have written. CourseNana.COM

    NOTE: Your project will not compile or run until you have created a test.cpp with a startTests() function. You can see how to do this in the next Section, Test Suite. CourseNana.COM

  • As usual, the code in start.cpp will print the project menu with options to either run the tests in test.cpp or call driver function for the project, ciphers(). Enter 1 to select executing your test cases starting with the startTests() function in test.cpp, enter 2 to select executing your ciphers starting with the ciphers() function in ciphers.cpptest_toUpperCase(), your program might run as follows (bold text represents your input): CourseNana.COM

-------------------------------
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**"
  • To begin, create a new project in Xcode or in Visual Studio and add caesar.hvigenere.hpolybius.hutility.hcaesar.cppvigenere.cpppolybius.cpputility.cpp, and ciphers.cpp to your project. Be sure that the files are copied and stored in the project directory. CourseNana.COM

    WARNING: When adding files to your project, be sure that the files are copied and stored in the project directory! CourseNana.COM

Test Suite

Creating test.cpp

  • As you write code, it’s important to test it! Catching and fixing bugs early is much easier than later on; this will save you hours when you work. So you’ll be required to create and submit a test suite for this project. CourseNana.COM

    NOTE: The best practice is to write tests before even implementing functions. Writing tests will make implementing the function faster/easier, PLUS it is infinitely satisfying to be able to test a function immediately once you’ve implemented it. CourseNana.COM

  • Create a new file and call it test.cpp. At the top of the file, put a multiline comment with the project’s name, your name and uniqname, your partner’s name and uniqname, if you have one, and a short description for this test file. This file will in fact test the functions declared in utility.hcaesar.hvigenere.h, and polybius.h so be sure to add these lines: CourseNana.COM

    #include "utility.h"
    #include "caesar.h"
    #include "vigenere.h"
    #include "polybius.h"

    after the multiline comment. Note that the filename is enclosed in double quotes "" and not angle brackets <>, which means that it’s a local file and not a system library. CourseNana.COM

    WARNING: Make sure that it’s #include "utility.h". Don’t #include "utility.cpp". CourseNana.COM

    NOTE: If you’re using Xcode and it gave you main.cpp with a main function, you won’t need it! So be sure to delete it. Or just rename main.cpp (from Xcode) to test.cpp; this way you don’t have to create a new file. CourseNana.COM

  • Next, write a startTests function in test.cpp. This file will test functions declared in utility.hcaesar.hvigenere.h, and polybius.h via standard output, so you’ll be calling those functions many times. Here’s a good way to start it: CourseNana.COM

    #include "utility.h"
    #include "caesar.h"
    #include "vigenere.h"
    #include "polybius.h"
    #include <iostream>
    #include <string>
    using namespace std;
    void testShiftAlphaCharacter();
    void startTests() {
    testShiftAlphaCharacter();
    // Repeat for all other functions to be tested
    return;
    }
    void testShiftAlphaCharacter() {
    cout << "Now testing function ShiftAlphaCharacter()" << endl;
    cout << "Expected: 'a', Actual: '" << shiftAlphaCharacter('a', 0) << "'" << endl;
    cout << "Expected: 'b', Actual: '" << shiftAlphaCharacter('a', 1) << "'" << endl;
    cout << "Expected: 'd', Actual: '" << shiftAlphaCharacter('b', 2) << "'" << endl;
    return;
    }
  • shiftAlphaCharacter does not print anything, it just returns a character. If you were to just call this function, nothing would be printed to the console. But shiftAlphaCharacter does return a char. And so in order to check the correctness of this function’s implementation, you have to print its return value. CourseNana.COM

  • When you test these functions, you may wish to pay close attention to the Requires clause of each function. For example, the Requires clause for shiftAlphaCharacter functions “requires” that c is an alphabetical character. This means that you can assume that this function will always receive an argument that is an alphabetical character. Furthermore, you should not be calling it from the test suite with a value that violates the Requires clause. Doing so will cause your test suite to fail the autograder. For example, don’t call shiftAlphaCharacter with an argument of '@'. CourseNana.COM

    WARNING: If you submit a test case that violates the Requires clause, we will stop grading that submission and you will receive a very low score. CourseNana.COM

  • As you work on the functions in utility.cpp, you should write some test cases first, then write the implementation, and then run the program to check if the implementation is correct. You should repeat this with functions in caesar.cppvigenere.cpp, and polybius.cpp. CourseNana.COM

List of Functions to Test

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

  • toUpperCase()
  • removeNonAlphas()
  • removeDuplicate()
  • charToInt()
  • shiftAlphaCharacter()
  • caesarCipher()
  • vigenereCipher()
  • fillGrid()
  • mixKey()
  • findInGrid()
  • polybiusSquare()

Submit Frequently

  • As you progress through the project, we encourage you to submit after completing each section of the project. Doing so will help to ensure that you have written each part correctly before moving onto building the next. CourseNana.COM

  • When you submit test.cpp, we will compile and run it with our correct implementation of utility.cppcaesar.cppvigenere.cpp, and polybius.cpp and with our buggy implementation of utility.cppcaesar.cppvigenere.cpp, and polybius.cpp so as to generate two different outputs. We will then compare two outputs. If there is any difference, you’ve successfully exposed a bug! The autograder does not go into the details of what the difference is, it only sees if there exists a difference. CourseNana.COM

    test1 CourseNana.COM

  • Remember that some functions do not print anything on their own; we have to print their return value, as with the function shiftAlphaCharacter(): CourseNana.COM

    cout << shiftAlphaCharacter('a', 0) << endl;
    cout << shiftAlphaCharacter('b', 2) << endl;
    cout << shiftAlphaCharacter('X', 5) << endl;
    cout << shiftAlphaCharacter('X', 50) << endl;
  • After you submit your test suite, you might see output that looks like this: CourseNana.COM

    bugs CourseNana.COM

    That means that your test suite exposed 1 out of th 13 bugs in the staff’s “buggy” implementations of the project and your score for the test suite is 0.9 out of 10 points. The total points you can earn on test.cpp is capped at 10 points. You do not need to find all of the bugs to receive all of the points. CourseNana.COM

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: CourseNana.COM

  • CAESAR_SHIFTALPHACHARACTER1
  • CAESAR_SHIFTALPHACHARACTER2
  • CAESARCIPHER
  • UTILITY_CHARTOINT
  • UTILITY_REMOVEDUPLICATE
  • UTILITY_REMOVENONALPHAS1
  • UTILITY_TOUPPERCASE
  • POLYBIUS_FILLGRID
  • POLYBIUS_FINDINGRID
  • POLYBIUS_MIXKEY
  • POLYBIUSSQUARE
  • UTILITY_CHARTOINT
  • UTILITY_REMOVEDUPLICATE
  • UTILITY_REMOVENONALPHAS2
  • UTILITY_TOUPPERCASE
  • VIGENERECIPHER

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.cppvigenere.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(). CourseNana.COM

toUpperCase()

string toUpperCase(string original);
  • This function converts all alphabetical characters in the string original to uppercase. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you call it and print its return value like this: CourseNana.COM

    cout << toUpperCase("Diag @ 11 p.m.") << endl;

    Then the following should print: CourseNana.COM

    DIAG @ 11 P.M.

removeNonAlphas()

string removeNonAlphas(string original);
  • This function removes all non-alphabetical characters from the string original. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you call it and print its return value like this: CourseNana.COM

    cout << removeNonAlphas("Diag @ 11 p.m.") << endl;

    Then the following should print: CourseNana.COM

    Diagpm

removeDuplicate()

string removeDuplicate(string original);
  • This function removes all duplicate characters except the first occurrence of it from the string original. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you call it and print its return value like this: CourseNana.COM

    cout << removeDuplicate("HELLOWORLD") << endl;

    Then the following should print: CourseNana.COM

    HELOWRD

charToInt()

int charToInt(char original);
  • This function converts the character original to its integer representation. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you call it and print its return value like this: CourseNana.COM

    cout << charToInt('1') << endl;

    Then the following should print: CourseNana.COM

    1

cctype Library Functions

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

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

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

This means you must never do the following: CourseNana.COM

if (isalpha(someCharVariable) == true) CourseNana.COM

Instead you should do something like this: CourseNana.COM

if (isalpha(someCharVariable)) CourseNana.COM

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. CourseNana.COM

// 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. CourseNana.COM

Art of Cryptography

  • This type of “art” deals with scrambling information, so that passwords, credit cards and other sensitive data are all the more secure. An example with which you might already be somewhat familiar is HTTPS, a secure version of HTTP (a protocol that web browsers use to communicate with servers). When a browser requests a webpage from a server via HTTPS (and the address of that webpage will begin with https://), all the data flowing between the browser and the server is encrypted (i.e. converted into seemingly meaningless characters). This is useful for logging into websites like Facebook, for credit card purchases on online stores such as Amazon, and especially so for accessing account information on banks’ websites.

caesar.cpp

Cæsar

  • History holds that Julius Caesar protected sensitive messages by “rotating” each letter by 3 positions, so A became DB became E, …​, Z became C: CourseNana.COM

    caesar CourseNana.COM

  • This type of cipher is know as a substitution cipher, i.e. each letter is substituted with another. In the case of Caesar’s cipher, we have a secret key that’s known only by those who are supposed to know the information that is shared. This secret key (k) is used to rotate (i.e. shift) each letter by k places, wrapping A to Z and a to z as needed. CourseNana.COM

  • For example, suppose that the secret key is 10 and the plaintext message is Meet me at the Diag at 11 p.m. We would encrypt this message by shifting each letter 10 places: CourseNana.COM

    Meet me at the Diag at 11 p.m.
    Wood wo kd dro Nskq kd 11 z.w.

    Notice how M became W, since W is 10 characters away from M. Similarly, t became dt is the 20th letter in the alphabet (and the English alphabet has just 26 letters), so after we get to z (26th letter), we go back to a and go through three more letters to find d. CourseNana.COM

  • Some additional notes: CourseNana.COM

    • A negative key would shift the letters back. So if the key were -3, E would become B and A would become X. CourseNana.COM

    • Because the English alphabet has just 26 letters, keys of -25, 1, 27, 53, etc. are equivalent. CourseNana.COM

    • This cipher will encrypt only uppercase and lowercase letters. This means that only alphabetical characters are shifted. Furthermore, uppercase letters will remain uppercase and lowercase letters will remain lowercase after shifting. All other characters will remain the same. CourseNana.COM

    • Decrypting Caesar cipher is fairly simple: it suffices to shift the letters the other way. CourseNana.COM

  • For more information (and history), check out http://en.wikipedia.org/wiki/Caesar_cipher. CourseNana.COM

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] CourseNana.COM

  • And now, an overview of functions that you must implement in caesar.cpp. Note that the functions that follow do not print anything on its own; instead they return the result.

shiftAlphaCharacter()

char shiftAlphaCharacter(char c, int n);
  • This function “requires” that the first argument that’s passed in, c, be a letter. So you may assume that it will only be called with an uppercase or a lowercase letter. And remember not to call this function with anything but alphabetical characters, not even in your test suite! CourseNana.COM

  • Shifting a character is illustrated by the same diagram you saw earlier. Suppose that you’re working with uppercase characters and n is 3. Then the characters would be shifted like this: CourseNana.COM

    caesar CourseNana.COM

  • Note that the letter must remain in the same case after you shift it. So if c is lowercase, it will remain lowercase when this function returns it; if c is uppercase, it will remain uppercase. CourseNana.COM

  • And this is how you can test shiftAlphaCharacter in test.cpp. Since the function itself does not print anything, we have to print its return value: CourseNana.COM

    cout << shiftAlphaCharacter('a', 0) << endl;
    cout << shiftAlphaCharacter('b', 2) << endl;
    cout << shiftAlphaCharacter('X', 5) << endl;
    cout << shiftAlphaCharacter('X', 50) << endl;

    You should get this output: CourseNana.COM

    a
    d
    C
    V

caesarCipher()

string caesarCipher(string original, int key, bool encrypt);
  • As its name suggests, this function encrypts or decrypts the string that’s passed in using the algorithm described above. CourseNana.COM

  • For example, suppose original is the string "Meet me at the Diag at 11 p.m."key is 42 and encrypt is true. Then calling caesarCipher and printing its return value in test.cpp CourseNana.COM

    cout << caesarCipher("Meet me at the Diag at 11 p.m.", 42, true) << endl;

    would cause the following to be printed: CourseNana.COM

    Cuuj cu qj jxu Tyqw qj 11 f.c.

    To decrypt a message, call caesarCipher with encrypt set to false: CourseNana.COM

    cout << caesarCipher("Cuuj cu qj jxu Tyqw qj 11 f.c.", 42, false) << endl;

    which would print CourseNana.COM

    Meet me at the Diag at 11 p.m.

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

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

vigenere.cpp

Vigenère

  • As you might imagine, Caesar cipher is not all that strong, since it only takes to go through at most 25 different keys to break it. (Interested in breaking the Caesar cipher? Check out this project’s S’more!) For this reason, the world (or the French?) came up with Vigenère cipher. It dates to the fifteenth century and is one of the truly great breakthroughs in the development of cryptography. For more information, check out http://en.wikipedia.org/wiki/Vigenère_cipher. CourseNana.COM

  • Vigenère cipher improves upon Caesar cipher by shifting letters using different keys. This sequence of keys is known as a keyword. Each letter in the keyword represents by how far the corresponding letter in the original message will be shifted (A and a represent 0, B and b represent 1, Z and z represent 25). CourseNana.COM

  • For example, suppose you still want to send that same secret message, Meet me at the Diag at 11 p.m. But this time, you’re more careful and are using Vigenère cipher with the key Squirrel! Here’s how to encrypt: CourseNana.COM

    plaintext: Meet me at the Diag at 11 p.m.
    key: SQUI RR EL SQU IRRE LS Q U
    ciphertext: Euyb dv ee lxy Lzrk ll 11 f.g.
  • We first converted each letter of the keyword to uppercase and removed all non-alphabetic characters. We also applied the key just to letters and repeated the keyword after its last letter. Since S is 18 characters away from AM is shifted by 18. CourseNana.COM

  • So putting it all together, you will need to do the following: CourseNana.COM

    • Convert all letters in the keyword to uppercase.
    • Remember to strip all non-alphabetic characters from the keyword.
    • The keyword can be of any length greater than 0 and repeats after its last character.
    • Apply the keyword only to alphabetical characters in the original message.
    • As in the Caesar cipher, Z wraps to A and z wraps to a.
    • Decrypting would shift the letters backward.
    • This cipher will encrypt and decrypt only uppercase and lowercase letters. This means that only alphabetic characters will be shifted. Furthermore, uppercase letters will remain uppercase and lowercase letters will remain lowercase after shifting. All other characters will remain the same.

vigenereCipher()

string vigenereCipher(string original, string keyword, bool encrypt);
  • Notice that this function “requires” that keyword contain at least one alphabetical character. This means that you every time you call this function the string you provide as the second argument needs to have at least one letter in it. Make sure this is true for you function calls when testing the function, as well as anywhere else in your code. CourseNana.COM

  • When you implement this function, be sure to follow the rules outlined above. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you try to encrypt the string "Meet me at the Diag at 11 p.m." with the keyword "Squirrel!" call it and print its return value like this: CourseNana.COM

    cout << vigenereCipher("Meet me at the Diag at 11 p.m.", "Squirrel!", true) << endl;

    Then the following ciphertext should print: CourseNana.COM

    Euyb dv ee lxy Lzrk ll 11 f.g.

    Remember that decrypting shifts the letters backward! As an example: CourseNana.COM

    cout << vigenereCipher("Euyb dv ee lxy Lzrk ll 11 f.g.", "Squirrel!", false) << endl;

    And this is the output: CourseNana.COM

    Meet me at the Diag at 11 p.m.

polybius.cpp

Polybius Square

  • While shifting characters based on a key is common in ciphers, another common approach is to construct a grid as a cipher. As the name may suggest, the Polybius Square is a device invented by the Ancient Greek historian and scholar Polybius. CourseNana.COM

  • Although Polybius did not intend for his device to be used as a cipher, the Polybius Square is said to have been used in the form of the “knock code” to signal messages between cells in prisons by tapping the numbers on pipes or walls. CourseNana.COM

  • The original grid consists of the English alphabet and the digits 0 through 9. CourseNana.COM

    CourseNana.COM

    Each letter is then represented by its coordinates in the grid, with the row number first and then the column number. For example, "EECS" becomes "04040230" in the original grid above. CourseNana.COM

  • The encryption process using a Polybius Square begins with generating a Mixed Square, using a keyword. Once the Mixed Square is generated, we replace each letter with the “coordinates” of the letter within the grid, reading across first and then down (i.e. row and then column). CourseNana.COM

  • As an example, we shall encrypt the plaintext “EECS” with the keyword “POLYBIUS”. CourseNana.COM

  • First we make the Mixed Square using the keyword. We start by filling in the squares in the grid with the letters of the keyword, ignoring repetitions, and then continue with the rest of the alphanumerical letters in its original order. CourseNana.COM

    CourseNana.COM

  • With the Square complete, we simply find each plaintext letter in the grid, and replace it with its coordinates. So “E” becomes “15”, “C” becomes “13”, and “S” becomes “11”. With this, we get the ciphertext “15151311”. Note that each alphanumeric character is always represented by a pair of digits. CourseNana.COM

    CourseNana.COM

  • Decryption works in the reverse order, by translating the coordinates to its corresponding letter in the grid. CourseNana.COM

  • The Mixed square is generated in exactly the same way as we did before. CourseNana.COM

  • Imagine we received the ciphertext “435445” and the key is “POLYBIUS” again. Then “43” becomes “1”, “54” becomes “8”, and “45” becomes “3”. With this, we get the plaintext “183”. CourseNana.COM

CourseNana.COM

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. CourseNana.COM

fillGrid()

void fillGrid(char grid[SIZE][SIZE], string content);
  • Notice that this function “requires” that content be of length of 36. This means that you should never be passing a string that has a length that does not equal 36. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you try to fill the grid with the constant string ALNUM defined in utility.h. To test that your grid has been filled correctly, you should call the printGrid function implemented for you in utility.cpp. CourseNana.COM

    NOTE: SIZE is a constant in utility.h that represents the maximum dimension of the grid, which has the value 6. CourseNana.COM

    char grid[SIZE][SIZE];
    fillGrid(grid, ALNUM);
    printGrid(grid);

    Then the following content should print: CourseNana.COM

    --- --- --- --- --- ---
    | 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 | 0 | 1 | 2 | 3 |
    --- --- --- --- --- ---
    | 4 | 5 | 6 | 7 | 8 | 9 |
    --- --- --- --- --- ---

    We have implemented printGrid() for you, and its RME can be found in utility.h. Feel free to use this helper function when testing other functions in polybius.h. CourseNana.COM

mixKey()

string mixKey(string key);
  • Notice that this function “requires” that key does not contain duplicate characters and consists of only uppercase alphabet and numbers. This means that you do not have to handle duplicate characters or lowercase alphabet. You will later handle duplicate characters and lowercase alphabet in ciphers.cpp. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you try to mix the key "POLYBIUS", call it, and print its return value like this: CourseNana.COM

    cout << mixKey("POLYBIUS") << endl;

    Then the following content should print: CourseNana.COM

    POLYBIUSACDEFGHJKMNQRTVWXZ0123456789

    NOTE: Make use of the constant string ALNUM defined in utility.h. You should always begin with the alphabet and digits in their original order. CourseNana.COM

findInGrid()

string findInGrid(char c, char grid[SIZE][SIZE]);
  • Notice that this function “requires” that c is an uppercase alphabet or a digit. This means that you do not have to handle lowercase alphabet. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you call findInGrid with 'A' as c, a grid filled as follows, and printing its return value like this: CourseNana.COM

    char grid[SIZE][SIZE];
    fillGrid(grid, ALNUM);
    cout << findInGrid('A', grid) << endl;

    Then the following content should print: CourseNana.COM

    00

polybiusSquare()

string polybiusSquare(char grid[SIZE][SIZE], string key, string original, bool encrypt);
  • Notice that this function “requires” that key does not contain duplicate characters and consists of only uppercase alphabet and numbers. This means that you do not have to handle duplicate characters or lowercase alphabet. You will later handle duplicate characters and lowercase alphabet in ciphers.cpp. CourseNana.COM

  • When you implement this function, be sure to follow the rules outlined above. CourseNana.COM

  • As an example of how this function works, suppose in test.cpp you try to encrypt the string "EECS 183 is the best" with the keyword "183" call it and print its return value like this: CourseNana.COM

    char grid[SIZE][SIZE];
    cout << polybiusSquare(grid, "183", "EECS 183 IS THE BEST", true) << endl;

    Then the following ciphertext should print: CourseNana.COM

    11110533 000102 1533 341411 04113334

    Remember that decrypting uses the same grid as encrypting! As an example: CourseNana.COM

    char grid[SIZE][SIZE];
    cout << polybiusSquare(grid, "183", "11110533 000102 1533 341411 04113334", false) << endl;

    And this is the output: CourseNana.COM

    EECS 183 IS THE BEST

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

ciphers.cpp

WARNING: Sanity check! At this point, utility.cppcaesar.cppvigenere.cpp, and polybius.cpp should have implementations of all functions that we declared in utility.hcaesar.hvigenere.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. CourseNana.COM

Overview

  • Note: The autograder tests for ciphers.cpp test only your ciphers.cpp file. The autograder tests for ciphers.cpp will use EECS 183 staff implementations for the other files, like caesar.cpp. A common problem students encounter in implementing functions in ciphers.cpp is violating the Requires clause of RMEs for the functions in the other files, like caeser.cpp, vigenere.cpp, and polybius.cpp. If your solution seems to work on your computer, but fails test cases in the autograder for ciphers.cpp, check very carefully that you are not providing an argument from a function call in ciphers.cpp that would violate the Requires of the RME for that function. CourseNana.COM

  • As your last task involving ciphers, create a program that asks the user for a cipher (Caesar, Vigenere, or Polybius), whether the user would like to encrypt or decrypt a message, asks for the message and then for a key. Finally, the program should print the encrypted or decrypted message, as specified by the user. CourseNana.COM

  • At the top of the file, you’ll notice this line that lets ciphers.cpp use functions that are declared in utility.hcaesar.hvigenere.h, and polybius.h: CourseNana.COM

    #include "utility.h"
    #include "caesar.h"
    #include "vigenere.h"
    #include "polybius.h"

    after the multiline comment. CourseNana.COM

  • Implement the ciphers function in ciphers.cpp. Let us recommend this structure: CourseNana.COM

    void ciphers() {
    // ask user for cipher (Caesar, Vigenere, or Polybius)
    // ask user to encrypt or decrypt
    // get message from user
    // get key or keyword from user
    // encrypt or decrypt message using selected cipher and key(word)
    // print encrypted/decrypted message
    }
  • When you ask the user for input be sure to use these prompts, followed by a single space, in this order: CourseNana.COM

    When encrypting, CourseNana.COM

    Choose a cipher (Caesar, Vigenere, or Polybius):
    Encrypt or decrypt:
    Enter a message:
    What is your key:
    The encrypted message is:

    Or when decrypting, CourseNana.COM

    Choose a cipher (Caesar, Vigenere, or Polybius):
    Encrypt or decrypt:
    Enter a message:
    What is your key:
    The decrypted message is:

    Expect the user to be bad at capitalization and accept input ignoring the case, such as CourseNana.COM

    cAEsar
    vigenEre
    POLYBIus
    ENCRYPT
    decrypt

    You must also accept cvpe and d (or uppercase versions) as valid input. If an invalid cipher type or mode (encrypt or decrypt) is entered, you must print out the message Invalid cipher! or Invalid mode!. CourseNana.COM

    We recommend using getline to read strings, so as to read more than just the first word of the keyword or message. CourseNana.COM

    NOTE: For the caesar cipher, you can assume the user will always enter a key that is an integer when they have selected to use a Caesar cipher. CourseNana.COM

  • Then print the encrypted/decrypted message on the same line. CourseNana.COM

  • Because you’ll probably be repeating some code in ciphers.cpp, like prompting the user for a string and reading that string, it’s a good idea to factor out common functionality into separate functions. Declare those functions in ciphers.cpp (not in utility.h) above ciphers and implement them below ciphers. Be sure to write RME comments above those functions’ declarations to maximize style points. CourseNana.COM

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

  • So that we can automate some tests of your code, your program must behave peIf the user enters an invalid mode (anything other than what is defined above), print Invalid mode!, and exit the program, i.e., return; from ciphers().
  • For Caesar Cipher, you can assume that the user will always enter an integer-valued key when they have selected to use the Caesar Cipher. You do not need to handle the case where they enter a non-integer key. CourseNana.COM

  • For Vigenere Cipher, you must ensure that the keyword contains at least one alphabetical character. If not, print Invalid key!, and exit the program, i.e., return; from ciphers(). CourseNana.COM

  • For Polybius Square, you must ensure that the message is valid. That is, you must verify that all characters are alphanumeric or a space. Lowercase letters are valid, but the message must be converted to uppercase before calling the polybiusSquare function. CourseNana.COM

    If an invalid message is entered, you must print Invalid message!, and exit the program, i.e., return; from ciphers(). CourseNana.COM

  • For Polybius Square, you must ensure that the key is valid. That is, you must verify that all characters are alphanumeric, all characters are uppercase, and that there are no duplicates. To ensure this, the key must be converted to uppercase, and duplicates must be removed from the key before calling the polybiusSquare function. Non-alphanumeric characters in the key should not be removed, but instead should result in an error message. CourseNana.COM

    If an invalid key is entered - containing anything other than alphanumeric characters - you must print Invalid key!, and exit the program, i.e., return; from ciphers(). CourseNana.COM

  • HINT: think of which functions in utility.h you can use to accomplish the above requirements. CourseNana.COM

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. CourseNana.COM

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

Sample Run 1 CourseNana.COM

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 CourseNana.COM

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 CourseNana.COM

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 CourseNana.COM

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 CourseNana.COM

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 CourseNana.COM

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 CourseNana.COM

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

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. CourseNana.COM

Function Table

  • The table below provides an outline of which other functions each function should call, if any.

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. CourseNana.COM

FileFunctionOther functions it should call
utility.cpptoUpperCase()Does not utilize any other functions
utility.cppremoveNonAlphas()Does not utilize any other functions
utility.cppcharToInt()Does not utilize any other functions
utility.cppremoveDuplicate()Does not utilize any other functions
caesar.cppshiftAlphaCharacter()Does not utilize any other functions
caesar.cppcaesarCipher()shiftAlphaCharacter()
vigenere.cppvigenereCipher()toUpperCase()removeNonAlphas()shiftAlphaCharacter()
polybius.cppmixKey()removeDuplicate()
polybius.cppfillGrid()Does not utilize any other functions
polybius.cppfindInGrid()Does not utilize any other functions
polybius.cpppolybiusSquare()mixKey()fillGrid()findInGrid()charToInt()

Here is an example of how to read the table: CourseNana.COM

  • caesarCipher() should call shiftAlphaCharacter()

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. CourseNana.COM

Get in Touch with Our Experts

WeChat (微信) WeChat (微信)
Whatsapp WhatsApp
Michigan代写,EECS183代写,Elementary Programming Concepts代写,Ciphers代写,C++代写,Encryption Algorithm代写,Cryptography代写,Polybius Square代写,Michigan代编,EECS183代编,Elementary Programming Concepts代编,Ciphers代编,C++代编,Encryption Algorithm代编,Cryptography代编,Polybius Square代编,Michigan代考,EECS183代考,Elementary Programming Concepts代考,Ciphers代考,C++代考,Encryption Algorithm代考,Cryptography代考,Polybius Square代考,Michiganhelp,EECS183help,Elementary Programming Conceptshelp,Ciphershelp,C++help,Encryption Algorithmhelp,Cryptographyhelp,Polybius Squarehelp,Michigan作业代写,EECS183作业代写,Elementary Programming Concepts作业代写,Ciphers作业代写,C++作业代写,Encryption Algorithm作业代写,Cryptography作业代写,Polybius Square作业代写,Michigan编程代写,EECS183编程代写,Elementary Programming Concepts编程代写,Ciphers编程代写,C++编程代写,Encryption Algorithm编程代写,Cryptography编程代写,Polybius Square编程代写,Michiganprogramming help,EECS183programming help,Elementary Programming Conceptsprogramming help,Ciphersprogramming help,C++programming help,Encryption Algorithmprogramming help,Cryptographyprogramming help,Polybius Squareprogramming help,Michiganassignment help,EECS183assignment help,Elementary Programming Conceptsassignment help,Ciphersassignment help,C++assignment help,Encryption Algorithmassignment help,Cryptographyassignment help,Polybius Squareassignment help,Michigansolution,EECS183solution,Elementary Programming Conceptssolution,Cipherssolution,C++solution,Encryption Algorithmsolution,Cryptographysolution,Polybius Squaresolution,