C.I.S. 1.5 (Science Section)
Professor Langsam
Assignment #5
Cryptography is the practice and study of hiding information. In modern times, cryptography is considered to be a branch of both mathematics and computer science, and is affiliated closely with information theory, computer security, and engineering. Cryptography is used in applications present in technologically advanced societies; examples include the security of ATM cards, computer passwords, and electronic commerce, which all depend on cryptography.[1]
Text that has not been encrypted is known as plaintext or cleartext. Encrypted plaintext is called ciphertext, and can not be read until it is decrypted.
An excellent introduction to cryptography has been published by the PGPi Project[2] and is available online from:
http://www.pgpi.org/doc/guide/6.5/en/intro/
One of the earliest known cryptographic methods is known as Caesar’s Cipher. The following description is taken from the above reference:
An extremely simple example of conventional cryptography is a substitution cipher. A substitution cipher substitutes one piece of information for another. This is most frequently done by offsetting letters of the alphabet. Two examples are Captain Midnight’s Secret Decoder Ring, which you may have owned when you were a kid, and Julius Caesar’s cipher. In both cases, the algorithm is to offset the alphabet and the key is the number of characters to offset it. For example, if we encode the word “SECRET” using Caesar’s key value of 3, we offset the alphabet so that the 3rd letter down (D) begins the alphabet.
So starting with
ABCDEFGHIJKLMNOPQRSTUVWXYZ
and sliding everything up by 3, you get
DEFGHIJKLMNOPQRSTUVWXYZABC
where D=A, E=B, F=C, and so on.
Using this scheme, the plaintext, “SECRET” encrypts as “VHFUHW.” To allow someone else to read the ciphertext, you tell them that the key is 3. Obviously, this is exceedingly weak cryptography by today’s standards, but hey, it worked for Caesar, and it illustrates how conventional cryptography works.
In Part 1 of this assignment you will first use Caesar’s Cipher to encode messages using a user supplied key. In Part 2 of this assignment you will use a brute force algorithm to crack a secret message that has been encoded using Caesar’s Cipher but for which the key is not available.
As you have learned, C++ represents characters by means of an ASCII Code which represents each character by an integer from 0 to 255. Thus the letter ‘A’ is represented by the integer 65, ‘B’ by the integer 66, and so on. The integer value of a character may be obtained by writing:
char c;
int x;
x = (int) c;
For purposes of this assignment we will limit ourselves to those characters whose ASCII values are between 32 and 126. These include the upper and lower case alphabet, punctuation marks and the space. All other characters are to be ignored.
Part I
Write a program that will read a file plaintext.txt and produce an encrypted file ciphertext.txt using a user supplied key. Any character whose ASCII values are not between 32 and 126 is to be ignored. Note that since there are 95 (126-32+1) valid characters, valid offset keys must be between 1 and 95 inclusive. Why?
Strategy:
1.
Have the main call a function getKey,
which asks for a key from the user and ensures that the key is valid.
2.
Have the main process each character in
the input file by:
a.
Call a function getCharacter,
which returns the next valid character taken from plaintext.txt, ignoring any characters
whose ASCII values are not between 32 and 126.
b.
Call a function, caesarsCipher,
which receives the plaintext character and the key as input parameters, and
writes the encrypted character to the encrypted file ciphertext.txt.
For example, if the key is 5 and the plaintext character is ‘Z’ the ciphertext
is ‘_’ (90+5 = 95; the ASCII value of ‘_’ is 95), while if the key is 10 the
ciphertext is ‘d’ (90+10 = 100; the ASCII value of ‘d’ is 100).
Note, that we must ensure that the shift is between ASCII 32 and 126. If the addition of key results in a value greater than 126 we continue counting from 32. This may be accomplished by saying:
int
key, encrypted;
encrypted = (c + key);
if
(encrypted > 126)
encrypted
= encrypted - 95;
For example, if the key is 10 and the plaintext character is ‘z’ the ciphertext is ‘%’ (122+10 = 132; 132-95 = 37; the ASCII value of ‘%’ is 37).
Part II
Write a function crackCaesarsCipher, which given a lower and upper range for valid keys, uses brute force to decrypt the secret message in the file secretMessage.txt.
Strategy:
Because there are no more than upper-lower+1 valid keys, it is relatively easy for a computer to try each possible key. Of course a human must examine the results in order to separate the gibberish from reasonable text.
1.
Have the main call the function crackCaesarsCipher
with input parameters lower and upper. This function:
a. Opens an output file decodedMessage.txt, and then
b.
Repeatedly
calls a function crack with each of the possible keys.
2.
crack receives a key as a
parameter and uses that key to decode the file. The function:
a.
Opens the file secretMessage.txt
b.
Reads the file character by character
c.
Prints the (possibly) decoded character
to the output file
d.
Closes the file secretMessage.txt
3.
Manually examine the decodedMessage.txt and report both the
message and the key that successfully decoded it.
For Part I use key = 15. The files plaintext.txt for Part I and secretMessage.txt for Part II can be found here: http://eilat.sci.brooklyn.cuny.edu/cis1_5/CISClassPage.htm
Be sure your program is neatly formatted and commented as discussed in class. Your program should be well structured (use functions, wherever appropriate), use meaningful variables and be well commented. All output is to be to a file. Submit your program and your input and output files.
C++ Programming Tidbit
As you are no doubt aware, when reading a file the system maintains an internal pointer that keep track of where it is up to in the file. Upon opening a file for the first time, the pointer points to the first character (byte) of the file. When the file is closed, the pointer remains pointing to the end of the file even if the file is later reopened.
In order to reread a file from the beginning, it is necessary to use the clear() method in order to reset the file pointer. Your code would look like the following:
infile.clear(); // REQUIRED!! Without it,
// the file
opens, but eof
// remains false
infile.open("input.txt"); // Reopen the file
//Read
and print the file, character by character
infile
>> c;
while(!infile.eof()){
// process
the character
…
// get the next character
infile >> word;
}
infile.close(); // Close the file