55.

Learn Encryption Techniques with BASIC and C++
(Publisher: Wordware Publishing, Inc.)
Author(s): Gil Held
ISBN: 1556225989
Publication Date: 10/01/98

Previous Table of Contents Next


The POLY2.CPP Program

The program POLY2.CPP, which represents the C++ language version of the POLY2.BAS program, was developed as a continuation of our strategy of providing encryption examples in both languages. Listing 5.7 includes the POLY2.CPP program listing. The actual program, as well as the executable version of the program, are located in the C directory on the CD-ROM. Concerning the executable version of the program, its filename follows the naming convention used in this book, resulting in the filename POLY2.EXE. To distinguish the executable versions of the BASIC and C++ programs from one another, it is important to remember that although they have the same filename, they are located in different directories. That is, the file POLY2.EXE located in the directory BASIC represents the executable version of the program POLY2.BAS while the file POLY2.EXE located in the C directory represents the executable version of the program POLY2.CPP.

Listing 5.7 The POLY2.CPP program listing.

 /*poly2.cpp C++ code written by Jonathan Held, April 1, 1998, using Microsoft's Visual C++ version 5.0. */ //standard includes #include<iostream.h> #include<assert.h> #include<string.h> #include<ctype.h> #include<fstream.h> //constants we will use const int FIVE = 5, TWENTYFIVE = 25, TWENTYSIX = 26,       TWENTYSEVEN = 27, SIXTYFIVE = 65, NINETY = 90,       NINETYTWO = 92, SIZE = 256, BIGSIZE = 1000; //function prototypes bool checkInput(char * &); void createStream(char *, char []); void createTable(char [][TWENTYSEVEN], const char [], const char []); void display(char *); void formatData(char []); bool encryptText(char *, char *, const char PTEXT[],                          const char [][TWENTYSEVEN], char []); char* formCipheredMessage(const char [], const char []                [TWENTYSEVEN],                const char[], char []); void getFileNames(char *&, char *&); int getInputType(void); int getKeyword(char *&); bool getMessage(char *, char *, const char [],               const char [][TWENTYSEVEN], char []); void groupBUFFER(ofstream, int); void printCipherToFile(ofstream, char[]); bool writeMatrixToFile(const char [], const char [][TWENTYSEVEN]); char BUFFER[BIGSIZE] = {'\0'}; //---------------------------------------------------------------- //Function: main() //Parameters: None //Return Type: int - 0 means program terminated normally //Purpose: Runs the main part of the program. //---------------------------------------------------------------- int main() {   char plaintext[TWENTYSEVEN] = {'A','B','C','D','E','F','G','H',                    'I','J','K','L','M','N','O','P',                    'Q','R','S','T','U','V','W','X',                    'Y','Z','\0'};   char *ptext_keyword, *ctext_keyword, *infile, *outfile;   //p_stream is used to help form the alphabetic-shifted cipher   //alphabets   char p_stream[TWENTYSIX] = {'\0'};   //c_stream represented the top row of the polyalphabetic ciphertext   //matrix   char c_stream[TWENTYSIX] = {'\0'};   //table is the actual polyalphabetic ciphertext matrix   char table[TWENTYSIX][TWENTYSEVEN], message_to_cipher[SIZE];   int type_of_input;   bool success = false;   cout << "Enter plaintext keyword or keyword phrase in UPPERCASE: ";   getKeyword(ptext_keyword);   cout << "Enter ciphertext keyword or keyword phrase in UPPERCASE: ";   getKeyword(ctext_keyword);   createStream(ptext_keyword, p_stream);   createStream(ctext_keyword, c_stream);   createTable(table, plaintext, c_stream);   getFileNames(infile, outfile);   type_of_input = getInputType();   //handle file input   if (type_of_input){      success = encryptText(infile, outfile, p_stream, table,                                  message_to_cipher);   }   //keyboard input   else {     success = getMessage(infile, outfile, p_stream, table,                               message_to_cipher);   }   //report success of operation   if (!success){      cerr << "Error: Invalid filename specified. Goodbye." << endl;   }   else {      cout << "Press return to display resulting enciphered message."                     << endl;      //get the newlines off the current input stream      cin.get();      if (type_of_input){         cin.get();      }      display(outfile);   }   writeMatrixToFile(p_stream, table);   delete [] ptext_keyword;   delete [] ctext_keyword;   return (0); }//end main() //---------------------------------------------------------------- //Function: checkInput() //Parameters: input - the keyword the user entered //Return Type: bool - true if the input string contains an error, //       false otherwise //Purpose: Checks the user's keyword for invalid characters. //---------------------------------------------------------------- bool checkInput(char * &input) {  bool error = false;  int count = strlen(input);  for (int ix=0; ix<count; ix++){    int char_value = static_cast<int>(*(input+ix));    //determine if the user did not enter an uppercase character    if ((char_value < SIXTYFIVE) || (char_value > NINETY)){       error = true;       cerr << "\aYou entered an invalid keyword!" << endl << endl       << "Re-enter keyword: ";       break;    } } //check for just the newline and no other characters entered if (count == 0){    cerr << "\aYou entered an invalid keyword!" << endl << endl    << "Re-enter keyword: ";    error = true; } return error; }//end checkInput() //---------------------------------------------------------------- //Function: createStream() //Parameters: input - the keyword the user entered //      stream - streams used in the polyalphabetic cipher //           matrix. //Return Type: None //Purpose: Creates a preliminary stream that will be used in //conjunction with the polyalphabetic cipher matrix. //---------------------------------------------------------------- void createStream(char *input, char stream[]) {   bool used[TWENTYSIX];   int index = 0,      count = strlen(input);   //no characters are initially used   for (int ix=0; ix<TWENTYSIX; ix++){     used[ix] = false;   } //keep track of each character used, start forming the keyword //alphabet for (int jx=0; jx<count; jx++){   //get each character of the input string (integer value)   int char_value = static_cast<int>(*(input+jx));   if (used[char_value-SIXTYFIVE]){      //do nothing - the character was already used   }   else {     //mark as used and add to the keyword alphabet     used[char_value-SIXTYFIVE] = true;     *(stream+index++) = static_cast<char>(char_value);   } } //go through the list of characters used - those which weren't //used should be added to the keyword alphabet for (int kx=0; kx<TWENTYSIX; kx++){   if (!(used[kx])){      *(stream+index++) = static_cast<char>(SIXTYFIVE+kx); } } stream[TWENTYSIX] = '\0'; return; }//end createStream() //---------------------------------------------------------------- //Function: createTable() //Parameters: tbl - the polyalphabetic ciphertext matrix we are //                  creating //      PTEXT - the plaintext alphabet we use to form //          shifted keyword alphabets; starting position //          within the plaintext alphabet is determined by //          the cipher stream //      CSTREAM - the cipher stream that represents the top //           row of the polyalphabetic ciphertext matrix //Return Type: None //Purpose: Creates a polyalphabetic ciphertext matrix.  Each character //in the cipherstream represents a row in the polyalphabetic ciphertext //matrix; this row is a shifted alphabet that starts at the character //subsequent to the cstream character. //---------------------------------------------------------------- void createTable(char tbl[][TWENTYSEVEN], const char PTEXT[],                 const char CSTREAM[]) {   for (int ix=0; ix<TWENTYSIX; ix++){     int start_pos = (static_cast<int>(CSTREAM[ix]) - SIXTYFIVE + 1) %                              TWENTYSIX;      for (int jx=0; jx<TWENTYSIX; jx++){           tbl[ix][jx] = PTEXT[(start_pos + jx) % TWENTYSIX];      }     tbl[ix][TWENTYSIX] = '\0';    }  return; }//end createTable() //---------------------------------------------------------------- //Function: display() //Parameters: name - the name of the file the user wants displayed //Return Type: None //Purpose: Echoes the resulting output file to the screen. //---------------------------------------------------------------- void display(char *name) {   ifstream infile(name, ios::in);   char input[SIZE];   if (!(infile)){      cerr << "Unable to open input file for display." << endl;   }   else {     while (infile.getline(input, SIZE, '\n')){      cout << input << endl;     }   }   cout << endl;   return; }//end display() //---------------------------------------------------------------- //Function: encryptText() //Parameters: inp_file - the name of the input plaintext file /       outp_file - the name of the output file to save the /              encrypted text /       PSTREAM[] - the top row of the polyalphabetic ciphertext /             matrix /       TBL[][] - the polyalphabetic ciphertext matrix /        encoded_msg[] - the message to be encoded //Return Type: bool, indicating success of operation //Purpose: Used to encrypt file input.  Takes each line of the input //file, encrypts it, and saves the result to the specified output //file. //---------------------------------------------------------------- bool encryptText(char * inp_file, char * outp_file, const char PSTREAM[],           const char TBL[][TWENTYSEVEN], char encoded_msg[]) {   bool success = false;   char ip[SIZE];   //declare file stream objects   ifstream input(inp_file, ios::in);   ofstream output(outp_file, ios::app);   if ((!input) || (!output)){      //do nothing - I/O error; user will be notified upon      //procedure's return to main()   }   else {     success = true;     while (input.getline(ip, BIGSIZE, '\n')){      //check to see if the user wants the line to appear in plaintext      if (ip[0] == '/'){       if (strlen(BUFFER)>0){          //empty whatever is in the buffer          groupBUFFER(output, strlen(BUFFER));          //adjust the buffer          strcpy(BUFFER, (BUFFER+strlen(BUFFER)));          //output plaintext        }      output << ip << endl;      }      else {       //encipher the line       char *msg = formCipheredMessage(PSTREAM, TBL, ip, encoded_msg);       //print the cipher in groups of five to the ouput file       printCipherToFile(output, msg);      }   }  //empty the rest of the buffer  groupBUFFER(output, strlen(BUFFER));  //notify user where plaintext and ciphertext files are  cout << "Plaintext file is: " << inp_file << endl;  cout << "Encrypted file is: " << outp_file <<  endl << endl; }  //don't forget to close the files  input.close();  output.close();  //return success of the operation  return success; }//end encryptText() //---------------------------------------------------------------- //Function: formatData() //Parameters: data - the array we want to format //Return Type: None //Purpose: Get rid of all spaces in the array. //---------------------------------------------------------------- void formatData(char data[]) {   for (int mx=0, nx=0; (*(data+nx) != '\0'); nx++){     if (*(data+nx) == ' '){        //do nothing - skip over the space in the data     }     else {       *(data+mx++) = *(data+nx);     }   }   //don't forget to add the null terminator   *(data+mx) = '\0';   return; }//end formatData() //---------------------------------------------------------------- //Function: formCipheredMessage() //Parameters: PSTREAM - the top row of the polyalphabetic cipher matrix //      TBL - the actual polyalphabetic cipher matrix //      MESSAGETOCIPHER - the message we want to encipher //      enc_message - the enciphered message //Return Type: char* - a pointer to the encoded information. //Purpose: Encipher the user's message. //---------------------------------------------------------------- char* formCipheredMessage(const char PSTREAM[], const char TBL[]                [TWENTYSEVEN],                const char MESSAGETOCIPHER[], char enc_message[]) {  int length = strlen(MESSAGETOCIPHER)+1;  //location identifies where in the CSTREAM character the plaintext  //character is  int location = 0;  //use this variable to keep track of which cipher alphabet  //we are using - making it a static ensures that its value  //is preserved when we make subsequent function calls  static int which_cipher_alphabet = 0;  for (int ix=0; ix<length; ix++){   //test to see if we have an alphabetic character; if not,   //simply copy it to our encrypted message - this preserves   //characters such as ', ! etc...   if (!isalpha(static_cast<int>(MESSAGETOCIPHER[ix]))){         enc_message[ix] = MESSAGETOCIPHER[ix];   }   else {     //find the location of the character we want to        //encipher in the CSTREAM        for (int jx=0; jx<TWENTYSIX; jx++){          if (MESSAGETOCIPHER[ix] == PSTREAM[jx]){            location = jx;            break;          }        }        enc_message[ix] = TBL[which_cipher_alphabet%TWENTYSIX][location];        //go to the next cipher alphabet          which_cipher_alphabet++;     }  }  //return a reference to the encoded message  return enc_message; }//end formCipheredMessage() //---------------------------------------------------------------- //Function: getFileNames() //Parameters:  infile_name - the input file          outfile_name - the output file we will write the          enciphered text to //Return Type: None //Purpose: Get file information from the user. //---------------------------------------------------------------- void getFileNames(char * &infile_name, char * &outfile_name) {   char data[SIZE];   cout << "Enter filename to store/retrieve plaintext message: ";   cin >> data;   infile_name = new char[strlen(data) + 1];   strcpy(infile_name, data);   cout << "Enter filename to store enciphered message: ";   cin >> data;   outfile_name = new char[strlen(data) + 1];   strcpy(outfile_name, data);   cout << endl;   return; }//end getFileNames() //---------------------------------------------------------------- //Function: getInputType() //Parameters: None //Return Type: int - 0 indicates keyboard input, 1 indicates file //       input //Purpose: Determines if the user will be manually entering text to //be enciphered or if the user wants a file to be enciphered. //---------------------------------------------------------------- int getInputType(void) {   char type;   bool error = false;   int value;   do {      //prompt user for input from file or keyboard      cout << "Is file input from keyboard (K, k) or file (F, f): ";      cin >> type;      //make type an uppercase letter      type = static_cast<char>(toupper(static_cast<int>(type)));      //check for an invalid character      if ((type != 'K') && (type != 'F')){         cerr << "You have entered an invalid character!" << endl << endl;         error = true;      }      else {         if (type == 'K')            value = 0;        //value of 0 represents keyboard input            else value = 1;   //value of 1 represents file input         error = false;      }   } while (error);   cout << endl;   return value; }//end getInputType() //---------------------------------------------------------------- //Function: getKeyword() //Parameters: text - the keyword that the user enters //Return Type: int - the length of the keyword //Purpose: Prompts the user for a keyword and continues until //a valid keyword has been entered.  Returns the length of the //keyword. //---------------------------------------------------------------- int getKeyword(char * &text) {   bool error = false;   char buffer[SIZE];   do {    cin.getline(buffer, SIZE, '\n');    assert(text = new char[strlen(buffer) + 1]);    strcpy(text, buffer);    error = checkInput(text);    //delete text if there was an error    if (error){       delete [] text;      }   } while (error);   cout << endl;   return strlen(buffer); }//end getKeyword() //---------------------------------------------------------------- //Function: getMessage() //Parameters:  input - the name of the input plaintext file          output the name of the output ciphertext file          msg_to_cipher - the message to be encoded //       PSTREAM - the top row of the polyalphabetic ciphertext //            matrix; used to index into the actual table //       TBL - the polyalphabetic ciphertext matrix //Return Type: bool, indicating success of operation //Purpose: Allow the user to manually input text from the keyboard. //Save the text in plaintext to the input file; encrypt the text //and save it to the specified output file for later retrieval. //---------------------------------------------------------------- bool getMessage(char* input, char* output, const char PSTREAM[],                const char TBL[][TWENTYSEVEN], char msg_to_cipher[]) {   bool go_on = true, success = false;   ofstream textFile(input, ios::app);   ofstream cipherFile(output, ios::app);   if ((!textFile) || (!cipherFile)){      //do nothing - error will be noted to user later   }   else {     success = true;     //get the newline character off of the input stream     cin.get();     cout << "Enter the message in UPPERCASE or lowercase characters. "                        << endl     << "Non-alphabetic characters may be entered but are ignored."                        << endl     << "Use a / at the beginning of each line that should remain"                        << endl     << "in plaintext and a \\ on a separate line to indicate the"                        << endl     << "end of an enciphered message." << endl < <endl; while (go_on) {  //get the entire line, up to 256 characters  cin.getline(msg_to_cipher, SIZE, '\n');  //case user doesn't want the text to be encrypted  if (msg_to_cipher[0] == '/'){     if (strlen(BUFFER)>0){        //empty whatever is in the buffer        groupBUFFER(cipherFile, strlen(BUFFER));        //adjust the buffer        strcpy(BUFFER, (BUFFER+strlen(BUFFER)));     }     //output plaintext     textFile << msg_to_cipher << endl;     cipherFile << msg_to_cipher << endl;      }    //case user is done entering text    else if (static_cast<int>(msg_to_cipher[0]) == NINETYTWO){      go_on = false;      }      //encrypt the text      else {        textFile << msg_to_cipher << endl;        char enciphered_msg[BIGSIZE];        formCipheredMessage(PSTREAM, TBL, msg_to_cipher,enciphered_msg);        printCipherToFile(cipherFile,enciphered_msg);        }   }  //empty the rest of the buffer  groupBUFFER(cipherFile, strlen(BUFFER));  }  //close the files  textFile.close();  cipherFile.close();  //notify user where plaintext and ciphertext files are  cout << "\nPlaintext file is: " << input << endl;  cout << "Encrypted file is: " << output << endl << endl;  return success; }//end getMessage() //---------------------------------------------------------------- //Function: groupBUFFER() //Parameters: out - the output stream we are writing to         num - the number of characters we want to output //Return Type: None //Purpose: Output the buffer in groups of five characters at a //time. //---------------------------------------------------------------- void groupBUFFER(ofstream out, int num) {   for (int kx=0;kx<num;kx++){     if ((kx!=0) && (kx%TWENTYFIVE==0)){        out << endl;     }     if ((kx!=0) && (kx%FIVE == 0) && (kx%TWENTYFIVE!=0)){        out << " " << *(BUFFER+kx);     }     else {        out << *(BUFFER+kx);     }   }   out << endl;   return; }//end groupBUFFER() //---------------------------------------------------------------- //Function: printCipherToFile() //Parameters: op - the output file we are writing to //      msg - the cipher text we are displaying //Return Type: None //Purpose: Group the cipher in 5-block characters in the //specified output file. //---------------------------------------------------------------- void printCipherToFile(ofstream op, char msg[]) {   formatData(msg);   //check to see if there are more than 25 characters   //in the buffer; if so, print out as many groups of   //25 as possible   if (strlen(BUFFER) >= TWENTYFIVE){      int numchars = (strlen(BUFFER)/TWENTYFIVE)*TWENTYFIVE;      //print the contents of the buffer to the output stream      groupBUFFER(op, numchars);      //shift whatever is left in the buffer      strcpy(BUFFER, (BUFFER+numchars));      //append data to the buffer      strcat(BUFFER, msg);   }   //if buffer contents are less than 25, simply append the new   //data to the buffer   else if ((strlen(BUFFER) >= 0) && (strlen(BUFFER) < TWENTYFIVE)){   strcat(BUFFER, msg);   }   return; }//end printCipherToFile() //---------------------------------------------------------------- //Function: writeMatrixToFile() //Parameters: CSTREAM - the top row of the polyalphabetic cipher matrix //      TBL - the actual matrix //Return Type: bool - indicates success of the operation //Purpose: Prints the matrix to a file "table.dat" for future //reference. //---------------------------------------------------------------- bool writeMatrixToFile(const char PSTREAM[], const char TBL[][TWENTYSEVEN]) {   ofstream output("table.dat", ios::out);   bool success = false;   if (output){      success = true;      output << PSTREAM << endl << endl;      for (int ix=0; ix<TWENTYSIX; ix++)        output << TBL[ix] << endl;   }   cout << "Polyalphabetic matrix was written to file table.dat"        << endl << endl;   output.close();   return success; }//end writeMatrixToFile() //end file poly2.cpp 


Previous Table of Contents Next


Learn Encryption Techniques with Basic and C++
Learn Encryption Techniques with BASIC and C++
ISBN: 1556225989
EAN: 2147483647
Year: 2005
Pages: 92
Authors: Gil Held

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net