Cryptanalysis of a class of ciphers: This cryptanalysis project consists of a software implementation of an algorithm that tries to decrypt an L-symbol challenge ciphertext computed using a specific cipher. Informally speaking, your program's goal is to find the plaintext used to compute this ciphertext within a reasonable amount of time. Specifically, your program should print on screen something like "Enter the ciphertext:", obtain the ciphertext from stdin, apply some cryptanalysis strategy and output on screen something like "My plaintext guess is:" followed by the plaintext found by your strategy. In doing that, your program is allowed access to: The ciphertext (to be taken as input from stdin) A plaintext dictionary (to be posted on top of this web page), containing a number q of plaintexts, each one obtained as a sequence of space-separated words from the English dictionary Partial knowledge of the encryption algorithm used (to be described below). Your program is not allowed access to: The key used by the cipher. Part of the encryption scheme (to be detailed below). The plaintext is a space-separated sequence of words from the English dictionary; thus, each symbol is either a space or one of the 26 lower-case letters from the English alphabet and cannot be a special character, punctuation symbol or upper-case letter; the sentence may not be meaningful, for sake of simplicity. The key is a sequence of t numbers between 0 and 26. The ciphertext looks like a sequence of symbols from {,a,..,z}. A text file plaintext_dictionary_test1 containing a number u of L-symbol candidate plaintexts will be provided to you (as an attachment at the top of this page), and you should feel free to use its content as part of your code. A text file plaintext_dictionary_test2 containing a number v of English words will be provided to you (as an attachment at the top of this page), and you should feel free to use its content as part of your code. Your program will be run using different parameters (e.g., L=500, u=5, v=40, and t between 1 and 24), and on a number of challenge ciphertexts, each computed using a potentially different variant of the encryption scheme. Your program should return as output a guess for which L-symbol plaintext was encrypted. Each ciphertext will be computed from a plaintext selected in one of the following two ways: randomly and independently choosing one of the L-symbol plaintexts in Dictionary1 or concatenating words randomly and independently chosen from Dictionary2 (any two words being separated by a space, until one has an L-symbol plaintext). All the encryption schemes used have the following common features: The message space and ciphertext space are the set {,a,..,z}^L. In other words the message m can be written as m[1],...,m[L], where each m[i] is in {,a,..,z}, and the ciphertext c can be written as c[1],...,c[L], where each c[i] is in {,a,..,z} The key space is the set {0,..,26}^t. In other words the key k can be written as k[1],...,k[t], where each k[j] is in {0,..,26}, for j=1,..,t. The encryption algorithm computes each c[i] as the (lexicographic) shift of m[i] by k[j(i)] positions, where the computation of each j(i) is left unspecified and may depend on i,t,L. In other words, each ciphertext symbol c[i] is the shift of the plaintext symbol m[i] by a number of position equal to one of the key symbols, which symbol being chosen according to an undisclosed, deterministic, and not key-based, scheduling algorithm that is a function of i, t and L. Your program will be scored based on two tests. In the first test, your program will be run many times, each time on a new ciphertext, computed using the above encryption scheme and a plaintext randomly chosen from the plaintext_dictionary_test1, each time with a different scheduling algorithm. On the first execution, the scheduling algorithm will compute "j(i) = 1+ i mod t". On the other executions, the scheduling algorithms will be more and more complex variations of this one. In this test we will likely choose L=500, and a plaintext dictionary with u=5 plaintexts. In the second test, your program will be run a few times, each time on a new ciphertext, computed using a plaintext obtained as a space-separate sequence of words that are randomly chosen from a subset of the set of all English words (specifically, a few words randomly taken from word_dictionary_test2) and the above encryption scheme, with a different scheduling algorithm. In this test we will likely choose L=500 and v=40 words. The program will obtain the ciphertext from stdin, and finally return the output plaintext on stdout within x minutes (or else it will be declared to default to an incorrect guess); most likely, we will choose x = 1 on test 1 and x = 3 on test 2.