This goal of this homework assignment is to rewrite your cipher program from the first homework assignment, this time in OCaml.
You may work with a partner for this assignment if you adhere to the guidelines.
Specification
You are responsible for writing a file named cipher.ml containing two functions with the interface shown below. (See chapter 10 of Z&W's OCaml notes for a review of how interfaces correspond to function definitions.)
(* Takes a message and a pad to produce an enciphered message *) val encipher: string -> string -> string (* Takes an enciphered message and a pad to produce the plaintext message *) val decipher: string -> string -> string
Your file may also include additional helper functions as needed. To help you begin, here is a starter file with the above included.
We will continue with our test-based development style, so in addition to the two functions described above you should also include a sufficient number of tests to ensure that your two functions work correctly. Write these before you begin to develop your program. You may even wish to include tests for some of the helper functions you write. Put all your tests in a separate file named cipherTest.ml. You will compile all the files together with this command:
ocamlopt -o cipher assert.ml cipher.ml cipherTest.ml
Your tests can be mostly short. For example:
let test () : bool = encipher "Test" "AAAA" = "Test" ;; run_test "No shift on A" test
Details
The basic flow of your program should be similar to the way you solved the problem in Python. Where you probably used a for loop in Python, you should use structural recursion and pattern matching here. (You may wish to review the example of a double recursion over two lists at once, on page 66 of Z&W's OCaml notes.)
A few specific OCaml functions may come in useful for this assignment that we have not directly studied. They are listed below for your consideration. You may include these directly in your program or modify them as needed.
(* Converts a string to a char list *) let char_list_of_string (s :string) :char list = List.init (String.length s) (String.get s) (* Converts a char to a string *) let string_of_char (c :char) :string = String.make 1 c
In addition, you can use any function from the standard string and list libraries. The ith character of a string s can be read using s.[i] for example. The ith element of a list l can be read using List.nth i l, and the head and tail of the list are List.hd l and List.tl l. Finally, you may use code that you find in the OCaml Caesar cipher demo.
Extension to Files
To use your functions for enciphering and deciphering files, all that is needed is a function to read contents from the file into a string. This is not too difficult, but rather than making you write this I am providing the necessary code in two separate files which can be combined with your work to make a final executable. Download and save encipherFile.ml and decipherFile.ml in the same directory as your other files. Assuming all your test code is in cipherTest.ml rather than cipher.ml, you can compile the two programs as follows:
ocamlopt -o encipher cipher.ml encipherFile.ml ocamlopt -o decipher cipher.ml decipherFile.ml
Then you can run your programs from the command line by providing the name of the message and pad files. For example, if these are message.txt and pad.txt respectively, then here is a sample transcript showing how to encipher and decipher the message:
$ ./encipher message.txt pad.txt > secret.txt $ more secret.txt Crsa is rm ljnoend igesxf mysvqnz! $ ./decipher secret.txt pad.txt This is an amazing secret message! $
Note that the encoded message is stored in a file called secret.txt using a technique called output redirection.
Extra Hints
If you are really struggling with this assignment, I have prepared a pack of hints to help you out. Use this file only if you have to! Completing the homework without it is worth one point on the grading rubric. Only download if you plan to use.
Contains call signatures for each function in the solution, plus descriptions on how to complete each function. Here is the link
To Submit
- cipher.ml
- cipherTest.ml
- readme.txt containing your self-reflection on this assignment