Remember: You are encouraged to work with a partner.
Each program must follow these following guidelines:
float raiseRealToPower(float base, int exponent);
This function will raise base the power exponent. The base can be any floating point value (negative, positive, zero) and the exponent can be any integer value (negative, positive, zero).
After you have written this function, test that the function is working by displaying a table of the powers of 0.5 between -15 and +5. Your table should be similar, but necessarily exactly the same as this:
-15 32768.00000 -14 16384.00000 -13 8192.00000 -12 4096.00000 -11 2048.00000 -10 1024.00000 -9 512.00000 -8 256.00000 -7 128.00000 -6 64.00000 -5 32.00000 -4 16.00000 -3 8.00000 -2 4.00000 -1 2.00000 0 1.00000 1 0.50000 2 0.25000 3 0.12500 4 0.06250 5 0.03125
Write a program (called crypto.c) which implements several functions to allow for encrypting and decrypting text using a method that is just slightly better than a Caesar Cipher. The idea is that a shift value (an integer) and an initial key (a word or phrase, composed only of letters and spaces) is chosen to construct a key which will be used to encrypt a message. First, the initial key is manipulated to remove all duplicate letters and spaces to get a partial key. Next, we form the full key by appending any remaining letters in the alphabet that were not in the partial key to the end of the partial key in alphabetical order. Finally, we rotate the key to the left by shift value.
For example, suppose the initial key is cs is fantastic and the shift value is 8.
In the first step, we remove all duplicate letters and all spaces to get the partial key: csifant.
Next, we append all the remaining letters in the alphabet, in
order, to the end of the partial key to form the full key:
csifantbdeghjklmopqruvwxyz
Finally, we rotate the key to the left by the shift value.
Rotating a string is like rotating bits: each time we rotate the
string to the left, we move the left-most character to the end of
the string. Since our shift value is 8, our final key becomes:
deghjklmopqruvwxyzcsifantb
To encrypt a string using this key, picture the full alphabet written above the rotated key:
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 d e g h j k l m o p q r u v w x y z c s i f a n t b
To encrypt, each letter of the message is first located in the top row (the alphabet, in order) and replaced by the letter in the bottom row (our rotated key). To decrypt, do the reverse.
I have provided you with part of main to help with reading in strings, along with comments to help you understand what those lines do.
Your task is to write 3 functions and a main program that tests the functions. The prototypes for your functions should be:
The type void written before the function indicates that the function does not return a value.
The function makeKey takes a string key as its first argument, which is the initial key from which to construct a rotated key, and an integer shiftValue as its second argument, which is the amount to rotate the key. Following the algorithm above, the function will remove duplicates, extend the string to a full key, then rotate it using the shift value. It returns FALSE if it is passed an empty string. Otherwise it returns TRUE. Use #define to define TRUE as 1 and FALSE as 0; use typedef to define the Boolean type (see cs33/class/11-03/leapyear.c).
The function encrypt takes two arguments. The second argument, key, is a rotated key as prepared by makeKey. The first is a string (length less than or equal to 80 characters) to be encrypted. Nonalphabetic characters of data are not changed. The case (upper vs lower) of alphabetic characters should be preserved.
The function decrypt reconstructs an original message from an encrypted string passed to it in data using the rotated key passed to it as a parameter. Again, the case of alphabetic characters should be preserved.
makeKey is much harder to write than encrypt and decrypt. Start with the easier functions and test them using one (or both) of my keys shown below. Once you can successfully encrypt and decrypt, then go back and complete makeKey.
You would not ordinarily show the full key or show the plain text when encrypting, but I do so here for illustrative purposes and your program should, too. Underlined words were entered from the keyboard while the prgoram was running.
Enter the initial key: cs is fantastic Enter a shift value: 8 Rotated key is: deghjklmopqruvwxyzcsifantb Alphabet is: abcdefghijklmnopqrstuvwxyz Enter text to encrypt. Stop encrypting with an empty line. To encryption and beyond! Sw jvgztxsowv dvh ejtwvh! CS is fantastic GC oc kdvsdcsog Enter text to decrypt. Stop decrypting with an empty line. Sw jvgztxsowv dvh ejtwvh! To encryption and beyond! GC oc kdvsdcsog CS is fantasticHere's another run with another key you can try:
Enter the initial key: The quick brown fox jumps over the lazy dog Enter a shift value: 13 Rotated key is: fxjmpsvlazydgthequickbrown Alphabet is: abcdefghijklmnopqrstuvwxyz Enter text to encrypt. Stop encrypting with an empty line. November 3, 2011 Thbpgxpu 3, 2011 Enter text to decrypt. Stop decrypting with an empty line. F ipjupc gpiifvp A secret message
You may want to use some of the following C functions. My solution
does not include them all, but I list them here for your reference.
Be sure to use the man pages to figure out what header files
you might need to include (e.g. string.h, etc):
printf
fgets
strlen
toupper
tolower
isupper
islower
strchr
You can also type man string.h (or any other .h file provided by C, e.g. man ctype.h) to find out a list of functions provided by the .h file.
HINT: The char type is really a one-byte integer which you are interpreting as an ASCII character. Therefore, if you set a char variable to have the value 'a', you're really setting it to 97 (hexademical 0x61). Therefore, if you then add 1 to that char, it's value is now 98, which you will interpret as the ASCII character 'b'.