CS 1005, C Term 2000
Introduction to Programming
HW4 (due Feb. 25)

This page is located at http://www.cs.wpi.edu/~alvarez/CS1005/HW4/

Introduction

Your task in this assignment is to write a program that accepts a text file and a positive integer key value as inputs and encrypts the input file using the key, placing the encrypted result in an output file. Your program should have a decryption mode that recovers an encrypted file if the correct key value is provided. You can get extra credit for reporting problems in the user's input commands or in processing the files named by the user. This assignment involves the use of strings, numerical encoding of characters, and character-level processing of file streams.

Character encryption

The encryption method to be used in this assignment is based on shifting the integer representation of each character in the input file by a certain amount. If the shift value were 1, for example, then an 'A' would become a 'B', an 'i' would become a 'j', and so on. However, to make it harder for someone who intercepts the encrypted message to make sense of it, different shift amounts are used for different characters in the input file depending on their positions within the file. Therefore, there is really an entire sequence of shift values, one for each position.

The shift sequence is determined by an initial integer value called the key, in the following way. First, the srand ("seed rand") function from the cstdlib library is called with the initial key value as its argument. This "seeds" a pseudorandom number generator which can then be accessed through the function rand() (no arguments). Successive calls to rand() yield an apparently random sequence of integers that is actually completely reproducible from the given key value (this property is needed in order to make decryption possible). To keep the final shifted character encodings within the range 0-255, the remainders rand() % 127 are the ones actually used to shift the character encodings in the manner described above.

Instructions

  1. Review the material on strings and streams from recent lectures and from chapter 9 of Astrachan. Also see section 6.3.5. Remember that program examples that use strings and file streams are also available in the appropriate subdirectories of the directory named /cs/cs1005/ on the CCC Unix network.

  2. Log into your CCC Unix account. Create a subdirectory named HW4 inside your personal CS1005 directory, Keep all files for this assignment in that directory. Files containing an outline of the main source file hw4.cxx for this assignment as well as the specification file io.h and implementation file io.cxx for two needed input/output functions may be found in the /cs/cs1005/samples/hw4/ directory. Copy these files to your personal HW4 directory.

  3. Read the specifications of the functions named GetString and GetInteger that appear in the header file io.h. Implement these functions, filling in the function bodies in the implementation file io.cxx. Do not change the header file io.h. Place any necessary #include directives at the top of the io.cxx file. Keep in mind that you can get partial credit for implementing GetInteger without checking that the input represents a valid positive integer.

  4. Write an outline of the main() function in hw4.cxx. Do not change the headers/prototypes of any of the functions in hw4.cxx. The user should first be prompted to enter the names of the input and output files, then prompted to choose between encryption and decryption modes, and then prompted to enter the key value. If the input values are valid, the program should attempt to process the files according to the input data. You may want to postpone implementing the actual file processing, including encryption and decryption, until you've got a prototype that approximates the desired interface behavior. A sample run illustrating the desired interface behavior of the program may be found here.

  5. Implement the Encrypt function in hw4.cxx. This function should declare appropriate ifstream and ofstream objects, bind them to the input and output files, call srand(key) to initialize the C++ pseudorandom number generator, and then iteratively read a character from the input file, encrypt it by calling Encrypted with this character and the shift value provided by nextshift as arguments, and write the encrypted character to the output file. All files should be closed and the appropriate bool status value returned. Here is an example of a typical input file and the corresponding encrypted version using a key value of 2000. I suggest that you implement the status checking last, so as to be able to concentrate on the main elements of encryption and file processing when you're starting out.

  6. Implement the Decrypt function in hw4.cxx. This should be fairly straightforward once you've implemented Encrypt. Decrypt should be able to recover an encrypted file exactly (whitespace and all) when given the key value used to encrypt the file. If you'd like to check your implementation, try decrypting the encrypted file referred to above, or try the following mystery file. The latter file was encrypted with a key value of 5, and so it should be readable if it is correctly decrypted with 5 as the key value. Be careful not to insert any extra characters into the encrypted files. Save them as plain text files with no formatting. If you need to transfer them by ftp, do so in binary mode. Remember: you don't need to worry about these particular encrypted files at all - I'm providing them in case you'd like to try them. However, your program will be tested with similar files and should handle them correctly.

  7. For extra credit: implement user input and file status validation for your program. If the mode or key are invalid, the program should report failure. Mode validation should be implemented in hw4.cxx. Key validation should be implemented in GetInteger in io.cxx. File status validation should be implemented in connection with Encrypt and Decrypt in hw4.cxx. Only strings representing positive integers should be accepted by GetInteger, and any problems in reading from or writing to files should lead to an error message. For the latter, you do not need to state what specific problems were encountered, just the fact that there were file errors. See the sample run for an example. Key input error occurs when nonnumerical characters are present in the input stream; sources of file errors include a nonexistent input file and a write-protected output file.

  8. Compile and link the files for your assignment using the following command line:
       g++ -Wall -o hw4prog hw4.cxx io.cxx
    
    The -Wall option instructs the compiler to report all warnings. Debug your program as necessary. Test your program for different files and key values. Once you're satisfied that your program is behaving as desired, generate a script file named hw4.script that shows several runs of your program. To do this, just type script hw4.script at the Unix prompt. Then run your program as usual. When you're done, type exit to discontinue the logging process.

  9. The source code for your program in hw4.cxx should be commented in detail. Provide additional documentation for your code in a file named hw4.readme, following the WPI CS documentation standard.

Grading

Your program will be graded based on syntactical soundness, functionality, style, and documentation (including sample runs), with points awarded as indicated below. Note that it's possible to get up to 20 bonus points for this assignment.

Deliverables

Use turnin to submit the following files (and no other files), fully addressing the items listed above, before 3 pm on Friday Feb. 25, 2000.
  1. hw4.cxx
  2. io.cxx
  3. hw4.readme
  4. hw4.script