/* * This is a possible solution to the cipher_function2.cpp program that you were asked to write * for this week. It builds upon the cipher_function.cpp program by adding 4 new functions. Three * of these functions correspond to each of the three ciphers, and take three integers as * paramters. Once of these parameters is used to generate a (or two in the affine case) random * number between 0 and that parmeter minus 1. The other two parameters, and the random number(s) * are then passed into the original encoding functions from last week. The final new function is * the familiar rand_0toN1 function used to generate random numbers from 0 to N-1. A constant * value arr_size is also declared with a #define directive (see page 122 of Overland for * description) and used in place of the array size and modulus throughout the program in order to * make it easy to modify the size of the array without changing multiple entires. * The main function tests all three of the random versions of the ciphers. Note that we still have * not resolved the issue of gcf(multkey, mod) != 1 for the multiplicative and affine ciphers. * */ //Remember tht there are a bunch of libraries that need to be included if we are generating random //numbers. #include #include #include #include #define arr_size 20 using namespace std; //A list of all the functions. void add_cipher(int key, int mod, int n); void mult_cipher(int key, int mod, int n); void affine_cipher(int key1, int key2, int mod, int n); void add_cipher_rand(int mod, int n, int range); void mult_cipher_rand(int mod, int n, int range); void affine_cipher_rand(int mod, int n, int range); void set_array(int n); int rand_0toN1(int n); //Set the global array, and give it length arr_size. int A[arr_size]; int main() { //Here we will just initialize one variable, which will be the range of the random numbers //passed into the rand versions of the cipher functions. int range; //Set the seed for random number generation. srand(time(NULL)); //Set all the array values to be the numbers 0 through arr_size-1. set_array(arr_size); //Prompt to get the range from which the random key values will be generated. cout << "Enter the range of the random cipher keys and press ENTER (note that the actual "; cout <<"keys will be from 0 to the number entered minus 1): "; cin >> range; cout << "The random encoding generated by an additive cipher is: \n"; //Implement the add_cipher_rand function, and then print out the results. Perhaps you can try //and guess from the output what the key was. add_cipher_rand(arr_size, arr_size, range); for(int i = 0; i < arr_size; i++) { cout << A[i] << ", "; } //Reset the values in A using the set_array function. set_array(arr_size); cout << "The random encoding generated by an multiplicative cipher is: \n"; //Implement the mult_cipher_rand funtion, print everything out, and then reset the array. mult_cipher_rand(arr_size, arr_size, range); for(int i = 0; i < arr_size; i++) { cout << A[i] << ", "; } set_array(arr_size); cout << "The random encoding generated by an affine cipher is: \n"; //Implement the affine_cipher_rand function, and print out the results. Don't worry about //resetting A since we are at the end of the program affine_cipher_rand(arr_size, arr_size, range); for(int i = 0; i < arr_size; i++) { cout << A[i] << ", "; } return 0; } //Addative cipher function. It takes 3 parameters: the key to add to each element of the array, the //modulus (which will typicaly be the number of letters in our alphabet if you recall from the //reading), and the length of the global array. Here the modulus is set to the correspond to the //range of values in the array, which implies, since the array values are numbered by their index //(i.e. A[2] = 2), that the modulus will be the size of the array. void add_cipher(int key, int mod, int n){ for(int i = 0; i < n; i++) { A[i] = (A[i] + key) % mod; } } //Multiplicative cipher function. It takes 3 parameters: the key to add to each element of the //array, the modulus (which will typicaly be the number of letters in our alphabet if you recall //from the reading), and the length of the global array. Here the modulus is set to the correspond //to the range of values in the array, which implies, since the array values are numbered by their //index (i.e. A[2] = 2), that the modulus will be the size of the array. Note that it does not check //if gcf(key, mod) = 1, which means that our correspondence between the original numbers and their //encoding may not be 1 to 1 as will be necessary for decoding. void mult_cipher(int key, int mod, int n){ for(int i = 0; i < n; i++) { A[i] = (A[i] * key) % mod; } } //Affine cipher function. This function takes 4 paramters: multkey which will be the multiplier, //addkey, which will be the addative portion, the modulus (which as in the above two cases is set //to be the length of the array since the array is numbered by its indicies), and the length of //the array. Note that as in the mult_cipher, we do not require that gcf(multkey, mod) = 1, and //thus the correspondence between the original message and the encoding may not be 1 to 1. void affine_cipher(int multkey, int addkey, int mod, int n){ for(int i = 0; i < n; i++) { A[i] = ((A[i] * multkey) + addkey) % mod; } } //Add_cipher_rand function takes three paramters: a modulus, the length of the array, and a range //of values from which to generate a random number. A random number from 0 to range - 1 is //generated using the rand_0toN1 function, and tha number is used as the key paramter in the //add_cipher function. When all is over it has encoded a message with an unknown key. void add_cipher_rand(int mod, int n, int range) { int r = rand_0toN1(range); add_cipher(r, mod, n); } //Mult_cipher_rand function is very similar to the add_cipher_rand funtion, except that it calls //the mult_cipher function, passing a random number from 0 to range-1 as the key. When all is done, //it has encoded a message with an unknown key. void mult_cipher_rand(int mod, int n, int range) { int r = rand_0toN1(range); mult_cipher(r, mod, n); } //Affine_cipher_rand function does the same thing as the add_cipher_rand and mult_cipher_rand //counterparts, but generates two different random numbers since it needs two keys. it then passes //these, the modulus, and range into the regular affine_ciper function. void affine_cipher_rand(int mod, int n, int range) { int r1 = rand_0toN1(range); int r2 = rand_0toN1(range); affine_cipher(r1, r2, mod, n); } //Set-array function simply sets the values in the global array variable so that each value is //equal to its index in the array. Notice that the function only takes one parameter since it only //needs to know is the length of the array. void set_array(int n){ for(int i = 0; i < n; i++) { A[i] = i; } } //The rand_0toN1 function that should be familiar by now. It takes an integer as a parameter, and //returns a number between 0 and that number minus 1. int rand_0toN1(int n) { return rand() % n; }