/* * This is the Add_Cipher.cpp program that should serve as a guide for constructing the cryptology * programs for the remainder of the term. It declares an Add_Cipher class, and tests its functions * in the main function. Note that the strings in the encode and decode functions are assumed to be * all lower case letters without spaces or punctuation marks. These are the types of strings we * will use for the remainder of the course for simplicity. It is possible to build classes that * allow for more complex strings, but it just amounts to more string parsing, and doesn't give * much more in the way of understanding the ciphers. * */ //We need all these include directives to do random number generation and ensure we can use the //Translator.h file. #include #include #include #include #include "Translator.h" using namespace std; //This is the class declaration for an additive cipher. class Add_Cipher { private: //We will need to use a modulus and a translator for our functions, but they should be made //private variables so they cannot be changed from outside the program. int mod; Translator tran; public: //These are all the public functions available to other users. They include the ability to //encode and decode strings, and a class constructor. Add_Cipher() {mod = 26;} void encode(string *str, int key); void encode_rand(string *str, int range); void decode(string *str, int key); private: //The rand number generation function is declared private since it is only used within one of //the public functions. int rand_0toN1(int n); }; int main() { string a = "bca"; Add_Cipher add; add.encode(&a, 40); cout << "After encoding: " << a << "\n"; add.decode(&a, 40); cout << "After decoding: " << a << "\n"; add.encode_rand(&a, 40); cout << "After random encoding: " << a << "\n"; return 0; } //Notice that this encode function is a little different from the ones we have previously created. //First, it takes a pointer to a letter string as a paramter instead of an array (a question to //ponder is why a pointer to a string instead of a string? Hint: the reason is analogous to to why //we must pass pointers to integers in a swap function. This makes sense since because //cryptological messages start and end wih letters; the number correspondence is an intermediate //stage that the end user doesn't need to know. The Translator object declared above will be used //to convert back and forth between strings and arrays of numbers. Also note that the modulus is not //a paramter here since in order to do proper encoding/decoding we need a set alphabet and number //correspondence with that alphabet. Since the size of this alphabet determines the modulus, we //take it as a given in the program and declare it inside the class. void Add_Cipher::encode(string *str, int key) { //Up until now we have not worried about whether the key was a positive number, but it really //should be. So, if the key is not positive prompt the user to enter a new key. We will allow 0 //since that will just be the identity for the additive cipher. Note, however, that you will //not want to allow a 0 key value for the multiplicative cipher (why?). while(key < 0) { cout << "Please enter a nonnegative key value: "; cin >> key; } //Get the length of the string we want to encode and make an array of that size that will //contain the corresponding numbers. int len = (*str).size(); int A[len]; //"Translate" the string into numbers, i.e. put the numbers corresponding to th lettes in the //message into an array. tran.string_to_num(str, A, len); //This should look familiar; it encodes the numbers. for(int i = 0; i < len; i++) { A[i] = (A[i] + key) % mod; } //Translate back and we are done. tran.num_to_string(str, A, len); } //A random encoding function that just generates the random encoding key, and lets actual encode //function do the rest of the work. If the range entered is less than 0 it prompts the user to //enter a positive number. void Add_Cipher::encode_rand(string *str, int range) { while(range < 0) { cout << "Please enter a nonnegative number for the range: "; cin >> range; } srand(time(NULL)); int num = rand_0toN1(range); encode(str, num); } //This decode function is similar to the encode function with one exception highlighted below. It //also ensures that a valid key has been entered by making sure the key value is nonnegative. void Add_Cipher::decode(string *str, int key) { while(key < 0) { cout << "The key value must be nonnegative, try another value please: "; cin >> key; } int len = (*str).size(); int A[len]; tran.string_to_num(str, A, len); for(int i = 0; i < len; i++) { A[i] = (A[i] - key) % mod; //We must add this extra while loop to ensure that all of the values fall between 0 and //mod-1. For example, imagine the original letter was z and we encoded it with a key of 10. //Then the encoded number would be 9, but in the above code that would turn into -1. Thus, //we need to keep adding our modulus while we are less than 0 to ensure the elements in the //array fall between 0 and mod-1 and therefore have a letter correspondence. while(A[i] < 0) { A[i] += mod; } } tran.num_to_string(str, A, len); } //Standard random number generation function. int Add_Cipher::rand_0toN1(int n) { return rand() % n; }