CS105: Introduction to Computer Programming: C++

Assignment #1: Decipher

Due

Tuesday, February 2nd at noon

Overview

This is an assignment that will help you get to know C++, and dive into using arrays. You'll have to figure out how to use Linux machines, find an editor that you like, write several functions to decipher some encrypted text, and compile and run your code in order to read the text.

You are going to write a program to decipher an encrypted file. You will input from standard in, and store the encrypted text. You will decipher the text or figure out the encryption pattern, then decrypt the text and print it to standard output.

The text (see files Neruda.in and Coleridge.in) is encrypted by having each letter of the alphabet rotated by a fixed amount. In order to decipher the text, you have to figure out the shift amount by first analyzing the most frequently occurring character in the text (only alphabetic characters - ignore others, and ignore case of letters when finding the frequency). The most common letter in the English language is "e", and therefore when you know the most frequently occurring character in the text (which signifies "e"), you will know the shift distance. For example, if the most frequent text character is "h", then you know the distance is 3 back because "h" is 3 away from "e", but notice to decrypt you have to rotate backwards through the alphabet. Note that the alphabet forms a circle, so rotating backwards 3 is the same as forwards by 23. Numbers, punctuation, and whitespace have not been rotated, only letters. When decrypting, you should preserve the case of letters - i.e. "H" becomes "E" and "h" becomes "e". When you decrypt the text, you have gotten it right if it looks like proper English (unlike the encrypted text).

The characters you will use come from the ASCII chart, which represents chars as numbers. "A" through "Z" are 65 through 90, and "a" through "z" are 97 through 122. However, you should not use these literals in your program - C++ will allow you to use a char as an int which gets the ASCII value. For example you can check if a char is upper case by saying: if ((c >= 'A') && (c <= 'Z')). You can also use standard library functions like isupper(c) and islower(c) (the proper library is included in the starting C++ file). You also might need to normalize a letter to the beginning of the alphabet before doing the rotation, for example, subtracting 'a' from a lower case char before rotating it the proper distance, and then adding 'a' back.

Instructions

These instructions assume that you're doing development on the CS department linux machines. I recommend using the CS department linux machines, but if you feel more comfortable using another development platform, that's fine. Eventually, you'll have to use the CS department machines to submit the assignment, but you can develop on any machine you're comfortable with. Just make sure to test your code on the department machines before turning it in!
  1. If you don't have a CS department account, you should request a new account.
  2. Log on to a CS department linux machine using your CS department login. Make sure you log into a Linux machine, not a Sun machine!
  3. Start up XWindows by typing
    startx
    If you're new to linux, you might want to get a friend to help you or come by office hours. Getting used to a new operating system can take some time.
  4. Open up a terminal window and make a new directory for this assignment called assignment1:
    mkdir assignment1
    And change to that directory:
    cd assignment1
    Now use your favorite text editor to edit this file I created to get you started called decipherA1.cpp.
  5. Write some code inside decipherA1.cpp (stubs are provided) that deciphers encrypted text, without using dynamic allocation:
    1. You will define a function max_frequency that takes a constant char array, figures out the most frequent char, and returns it.
    2. You will define a function rotate that takes a char array and an integer rotation distance, and rotates each alphabetic char in the array by the specified amount (using rules above).
    3. You will also have to write code in main to read in the encrypted text from standard in, create a char array to hold it, call the functions above, and print your deciphered text to standard out. The input files you can use to experiment on, piping them to your program, are Neruda.in and Coleridge.in. You can use the Unix pipe command (shown below) to take the contents of the file in using standard in.

    Compile and run your code like this:

      computer% g++ -Wall -Werror -o decipher decipherA1.cpp
      computer% ./decipher < Neruda.in  //using Unix pipe - contents of Neruda.in can be obtained with standard in
    
  6. Compile and run your code:
    1. Make sure you're in the same directory as your decipherA1.cpp file. If you type
      ls decipherA1.cpp
      you should see the name of the file listed on the screen, along with anything else that happens to be in that directory. Make sure your name is in the top of the file!
    2. Compile your file with this command:
      g++ -Wall -Werror -o decipher decipherA1.cpp
      If all goes well, you shouldn't see any error messages.
    3. Run your program by typing this command:
      ./decipher < Coleridge.in
      Whatever you've included in your main function should run, and any output that is generated should appear on your screen.
  7. When you're happy with your code, use the turnin program to submit your decipherA1.cpp file. Use jbsartor as the grader and assignment1 as the assignment name.
    turnin --submit jbsartor assignment1 decipherA1.cpp
    You can turn in your file as many times as you want - I will only take the last one submitted.

Submission Checklist

Extra Credit (+4%)

Answer the following questions in written form in comments after your name at the top of decipherA1.cpp.