CMSC 246 Systems Programming
Fall 2019

Assignment#4
Due: Friday October 4, 2019 11:59PM

If you are attending Grace Hopper, send me an email for a 48 hour extension

All code should following the style guidelines in https://cs.brynmawr.edu/Courses/cs246/fall2019/style.html

Book Code Cipher
The only provably secure method of encryption is the "book" cypher in which a "book" is used to create a cypher key. To explain the book cypher, first consider the Caesar cypher.

The Caesar cypher is one of the oldest known encryption techniques; it is attributed to Julius Caesar. It involves replacing each letter in a message with another letter that is a fixed number of positions later in the alphabet. For example, if each letter is replaced by one that is two positions after it, an A will be replaced by a C, an L by an N, etc. If the replacement goes past the letter Z, the cipher wraps around to the beginning of the alphabet. Thus, with the same shift (of two), a Y will be replaced by an A, and Z by B. More generally, the formula for Caesar encryption, assuming that the only thing encrypted is upper case letters, is ((ch-'A') + OFFSET) % 26 + 'A'.

The Book code cypher replaces the fixed offset of the Caesar cypher with an offset that is determined by the character in a text (classically the text is taken from a book, hence the name). The idea is that you and the person you are sending a message to agree on the book ahead of time. Then the encryptor picks a location in the book to start and encrypts the message. The encryptor sends the encrypted message to you along with the starting location in the book.

For example, suppose that the book is "The quick brown fox jumps over the lazy dog". Further suppose that you have agreed to skip over all non letters in the book and that any lower case letters should be changed to upper case in both the book and the text. Hence, the actual book to be used is

```THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG
```
Under these assumptions, the formula for a book code encryption is ((ch-'A') + (BOOKLETTER-'A')) % 26 + 'A'

For example, suppose that the text to be encoded is "GEOFF"
The table below shows 3 encryptions, the Caesar cypher with an offset of 5, the book cypher starting at 5 and the book cypher starting at 10:

OriginalCaesarBook, start=5Book, start=10
TextformulaResultEncryptedBOOK LetterformulaValueEncryptedBOOK LetterformulaValueEncrypted
G(6+5)%2611 LU(6+20)%260A R(6+17)%2623X
E(4+5)%259 JI(4+8)%2612M O(4+14)%2618S
O(14+5)%2519TC(14+2)%2616Q W(14+22)%2610K
F(5+5)%2610 KK(5+10)%2615P N(5+13)%2618S
F(5+5)%2610 KB(5+1)%266G F(5+5)%2610K
Hence the encryption of my name is "AMQPG" when the book starting point is 5 and "XSKSK" when the book starting point is 10. So even keeping the same book but changing the offset completely changes the encrypted text.
Decryption is analagous.

Program requirements:
1. Implement code to do book code encryption and decryption
2. The program must encrypt all letters. Everything else may be printed as in the original. (This is horrific for encryption.) Slightly better for encryption would be to simply not output non-characters. Although better, do not do this as it makes evaluating decryption harder.
3. All lower case letters should be converted to upper case.
4. The program should take as input from take command line the following arguments in exactly this order:
• 1 or 0: 1 means encrypt, 0 means decrypt.
• filename: the file to be encrypted (or decrypted)
• filename: the book to use for encryption/decryption (Yes I know it is supposed to be agreed upon beforehand and left implicit.)
• integer: the character offset in the book
For example if you were to execute the following (assuming you have compiled the program under the name cryptor):
```                 cryptor 1 sample.txt book.txt 241 > crypt.out
cryptor 0 crypt.out book.txt 241 > decrypt.out
```
then text in decrypt.out and sample.txt should be the same except as given by the rules above.
5. The program need not be terribly robust to poor user input, but it should at least not crash. That is, the program can simply exit if the command line input is incorrect
6. Output should be the encrypted (or decrypted) text.
7. The book should be less than 1000 characters long. (If the book is more than 1000 characters, you may stop reading after 1000 characters.)
8. The book and the text to be encoded must be read from a file
9. If, during encryption/decription the program gets to the end of the book, it should wrap back to the beginning of the book. (For real book coding systems, the book should be very long so that it is never wrapped as doing so could make the text decypherable.)
10. The program must be able to handle text of an unlimited length for encoding or decoding.
So, you should first read the book into memory, then read and encode/decode character by character.

You will write 2 versions of this code the book code cypher.
Version 1
Use standard array notation to work through the book. For instance, you might make the following function call to encrypt (You are not required to use this function name and arguments).
```	void encryptA(char * nameOfFileToBeEncrypted, int bookLength, char book[bookLength], int bookStartingPosition);
```
Hence, you might have an encryption formula like: ((ch-'A') + (book[i]-'A')) % 26 + 'A'
Version 2
Use pointers for the book. For instance, you might make the following function call to encrypt:
```	void encryptP(char * nameOfFileToBeEncrypted, int bookLength, char * book, int bookStartingPosition);
```
Hence, you might have an encryption formula like: ((ch-'A') + (*book-'A')) % 26 + 'A'

Scripting in Linux
Once done, you will need to show the sample runs of programs, as required below. In order to record the runs, you can use the Linux command `script`.
Go to your Assignment directory and enter the command: `script session`

You will get your command prompt back. Next, run each of the above programs as you normally would. Once done, enter the command: `exit` (or CTRL-D)

This will end your script session. If you now look a the contents of the session file, you will see that the entire interaction has been recorded in it (as a script!).

### What to submit:

Collect together is a single directory all of the following:
• All program files for this task. If you use a makefile for compilation, include that
• The book and text files you used to encrypt / decrypt in your script examples. Note that I will use other books and text files during testing.
• Script showing the use of your code to encrypt and decrypt using the book and text files. The script should show the encrypted form of the file. You should have several examples, showing your program working with differnt texts to be encode, differnt books and different starting points in books. This suggests that you will need at least 6 trials. You may do thsi in one script file or many; but you must make it clear what you have done in the README.
• Do NOT include compiled code.
• Do NOT include emacs temp files, or the temp files of any other program. For emacs these are of the form xxxx~ and #xxxx#
When you have everything ready in this directory go to the directory containing the one with the information you want to submit. For instance, suppose that the files specified above are in /home/YOU/cs246/a4. Then you should go to /home/YOU/cs246.
Use the submit program as follows:
```  /home/gtowell/bin/submit -c 246 -p 4 -d a4
```
This will package up everything in the directory a4 and submit it under your login name along with a timestamp of your submission date.