Thread: My little Caesar cipher emulator

  1. #1
    Registered User dead_cell's Avatar
    Join Date
    Jun 2002
    Posts
    44

    Talking My little Caesar cipher emulator

    Hey guys & gals,

    Wow, I haven't been on these boards in a while -- but now, I've been working on this for the past eight hours straight (don't ask why -- It's for an independant study) and I can't fall asleep, so I thought I'd post it here.

    It's an emulator of the famed Caesar Cipher, or shift cipher for encrypting messages back in Caesar's rule. I know it's VERY messy, so I'm posting it here to see if I can get any advice on how to make it nice & clean.

    Code:
    #include <iostream>
    #include <cctype>
    
    //=============================================
    //CAESAR:  Emulation of the classic Caesar 
    //         Cipher.  Written by Dead Cell
    //=============================================
    
    using namespace std;
    
    int main()
    {
    //declare a character buffer for the message (plaintext)
    //was char message[256]; before I found it wouldn't work with strlen() below...
    char message[256];
    int msg_index;
    
    
    //read in the 255-character message from the user
     std::cout<<"What is the message you wish to encrypt?\n\nPlease do not enter any special characters ~`!1@2#3$4%5^6&7*8(9)0_-+={[}]|\\:;\"\'<,>.?./\n";
    std::cin.getline(message, 255, '\n');
     for(msg_index = 0; msg_index < strlen(message); msg_index ++)
       {
     if(!isalpha(message[msg_index]) && message[msg_index] != ' ')
       {
         std::cerr<<"User entered a number or a special character into the stream"<<std::endl;
         return 1;
       }
       }
     msg_index = 0;
    
    //generate a 27-character array for the original alphabet
    char alpha_plaintext[26];
    
    //fill the array -- note, this is very painful, but I didn't think of any other way of doing it...
    //---------------------------------
    alpha_plaintext[0] = 'A';
    alpha_plaintext[1] = 'B';
    alpha_plaintext[2] = 'C';
    alpha_plaintext[3] = 'D';
    alpha_plaintext[4] = 'E';
    alpha_plaintext[5] = 'F';
    alpha_plaintext[6] = 'G';
    alpha_plaintext[7] = 'H';
    alpha_plaintext[8] = 'I';
    alpha_plaintext[9] = 'J';
    alpha_plaintext[10] = 'K';
    alpha_plaintext[11] = 'L';
    alpha_plaintext[12] = 'M';
    alpha_plaintext[13] = 'N';
    alpha_plaintext[14] = 'O';
    alpha_plaintext[15] = 'P';
    alpha_plaintext[16] = 'Q';
    alpha_plaintext[17] = 'R';
    alpha_plaintext[18] = 'S';
    alpha_plaintext[19] = 'T';
    alpha_plaintext[20] = 'U';
    alpha_plaintext[21] = 'V';
    alpha_plaintext[22] = 'W';
    alpha_plaintext[23] = 'X';
    alpha_plaintext[24] = 'Y';
    alpha_plaintext[25] = 'Z';
    alpha_plaintext[26] = '\0';
    //---------------------------------
    
    //okay, let's get the shift value from the user
    int shift_value;
    std::cout << "How many characters do you want to shift? (must be less than 25)"<<std::endl;
    std::cin >> shift_value;
    
    int index;
    
    char shift[1];
    
     if(shift_value == 0)
       {
         std::cerr<<"User entered 0 for shift value";
         return shift_value;
       }
     if(shift_value > 0 && shift_value < 26)
       {
         shift[0] = 'R';
         index = shift_value;
       }
     //FAILED SECTION -- CAESAR WILL NOT TAKE A NEGATIVE SHIFT
     /* if(shift_value < 0 && shift_value > -26)
       {
         shift[0] = 'L';
         index = shift_value;
       }
     */
     //END FAILED SECTION
    
    //whew!  now, lets generate the dynamic shift array with a for() function
    
    char alpha_cipherkey[26];
    int cipher_index;
    switch(shift[0])
    {
    	case 'R' :  //shift right
    		for(cipher_index = 0; cipher_index < 26; cipher_index ++)
    		{
    			if(index < 25)
    			{
    			alpha_cipherkey[cipher_index] = alpha_plaintext[index];
    			std::cout << alpha_plaintext[cipher_index] << " = " << alpha_plaintext[index] <<std::endl;
    				index ++; 
    			}else if(index == 25)
    			{
    			alpha_cipherkey[cipher_index] = alpha_plaintext[index];
    			std::cout << alpha_plaintext[cipher_index] << " = " << alpha_plaintext[index] <<std::endl;
    				index = 0;
    			}else
    			{
    				return 0;
    			}
    		}
    	break;
    	//FAILED SECTION -- CAESAR WILL NOT ASSIGN 'L' TO shift[];  THEREFORE, SKIP THIS SECTION AND QUOT IF THE NUMBER IS NEGATIVE
    	/*
    	case 'L' : //shift left
    		for(cipher_index = 26; cipher_index >= 0; cipher_index --)
    		{
    			if(index > 26)
    			{
    			alpha_cipherkey[cipher_index] = alpha_plaintext[index];
    			std::cout << alpha_plaintext[cipher_index] << " = " << alpha_plaintext[index] <<std::endl;
    				index --; 
    			}else if(index == 0)
    			{
    			alpha_cipherkey[cipher_index] = alpha_plaintext[index];
    			std::cout << alpha_plaintext[cipher_index] << " = " << alpha_plaintext[index] <<std::endl;
    				index = 25;
    			}else
    			{
    				return 0;
    			}
    		}	
    	break;
    	*/
    	//END FAILED SECTION
    	default : //something went wrong; kill the program
    	  std::cerr<<"User entered negative shift value\n";
    		return 1;
    	break;
    }
    
    //now that we have the alpha_plaintext[] array filled with characters, let's put them to good use.
    
    //take the message[256] and fetch the length of it
    //int msg_length = strlen(message);
    
    
    //now, using the length, go through the array and convert the entire thing to UPPERCASE (to make it easier on the parser later on)
    
    for(msg_index = 0; msg_index < 255; msg_index ++)
    {
    	message[msg_index] = toupper(message[msg_index]);
    }
    
    //now that that's over, let's make this thing swap the places of the letters by creating a buffer
    //that's as long as the length of the message and manually place each value by means of a for() 
    //loop
    
    char buffer_crypt[strlen(message)];
    msg_index = 0; //reset the message index for the array
    /*
    //alright, now let's declare a two-dimentional array for character swapping
    char alpha_swap[26][2];
    int upper_index;
    for(upper_index = 0; upper_index < 26; upper_index ++)
    {
    	alpha_swap[upper_index][upper_index] = {alpha_plaintext[upper_index], alpha_ciphertext[upper_index]};
    }
    */
    
    //now, let's do some swapping...
    int swapindex;
    swapindex = 0;
    
    for(msg_index = 0; msg_index < strlen(message); msg_index ++)
    {
    	//read the index from the message[] and search for the corresponding letter in the alpha_swap[x][] array
    	//then swap it into the buffer_crypt[x] with the value stored in the alpha_swap[][x] array
    
    	std::cout<<"My current character is "<< message[msg_index]<<".\n";
    	while(alpha_plaintext[swapindex] != message[msg_index])
    	  {
    	    swapindex ++;
    	  }	    
    	    std::cout<<"\tTrying ["<<msg_index<<"] = ["<<message[msg_index]<<"] ...\n";
    	    if(message[msg_index] == ' ')
    	      {
    	      buffer_crypt[msg_index] = '-'; //swap the space with a hyphen
    	      std::cout<<"\tSwapped a space for a hyphen(-).  \n";
    	      swapindex ++;
    	      }
    	    if(message[msg_index] == alpha_plaintext[swapindex])
    	      {
    		buffer_crypt[msg_index] = alpha_cipherkey[swapindex]; //swap the characters
    		std::cout<<"\tSwapped "<<message[msg_index]<<" with "<<alpha_cipherkey[swapindex]<<".  \n";
    		swapindex ++;
    	      }
    
    	    //FAILED SECTION FOR PARSING NUMBERS.  IF NUMBER IS ENCOUNTERED, CAESAR WILL SKIP OVER IT
    	    /* if(!isalpha(message[msg_index]) && !ispunct(message[msg_index]) && message[msg_index] != ' ')
    	      {	      
    	      buffer_crypt[msg_index] = (message[msg_index] + shift_value); //swap the number with number + shift_value
    	      std::cout<<"\tSwapped a "<< message[msg_index] << "  for a "<< buffer_crypt[msg_index] << ".\n";
    	      swapindex ++;
    	      }
    	    */
    	    //END FAILURE SECTION
    		
    	    swapindex = 0;
    }
    	    
    //DONE!!!
    
    //okay, if everything went well, we can output the final encrypted message...
    
    std::cout<<"Your original message was...\n\n";
    int msg_out;
    for(msg_out = 0; msg_out < strlen(message); msg_out ++)
    {
      std::cout<<message[msg_out];
    }
    std::cout<<"\nYour Encrypted message is...\n\n";
    
    for(msg_out = 0; msg_out < strlen(message); msg_out ++)
    {
      std::cout<<buffer_crypt[msg_out];
    }
    
    return 0;
    }
    As I said above, it's VERY MESSY!!! I'm normally not like this, so any help organizing this is of great help. All I needed this to do is compile and run (which is does nicely on Linux), and by the time you've read through the code, it will have already been handed in. I'm just looking for any suggestions on how to spruce it up.

    Thanks,

    Dead Cell
    Linux is great - It does infinite loops in five seconds!

    ~Linus Torvalds

  2. #2
    Registered User dead_cell's Avatar
    Join Date
    Jun 2002
    Posts
    44

    ack, line formatting

    BTW: pardon the line formatting -- emacs isn't nice when it comes to doing direct copying into gedit, and then to an HTML form.

    Sorry about that,

    Dead Cell
    Linux is great - It does infinite loops in five seconds!

    ~Linus Torvalds

  3. #3
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    To start, you could at least make an encrypt and decrypt function, rather than cramming it all into main()
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  4. #4
    Senior Member joshdick's Avatar
    Join Date
    Nov 2002
    Location
    Phildelphia, PA
    Posts
    1,146
    I suggest using a vector of chars rather than an array. Then, you wouldn't have to worry about the length of the user's input, and you could use vector.size() instead of strlen().

    You've definitely made this too complicated. Think about the algorithm in terms of how you would do it. You'd just have one for loop to encrypt. All you do is add the key to the plaintext mod 26. To decrypt, that's just another function with one other for loop that subtracts the key from teh plaintext mod 26.

    That's all there is to it.
    FAQ

    "The computer programmer is a creator of universes for which he alone is responsible. Universes of virtually unlimited complexity can be created in the form of computer programs." -- Joseph Weizenbaum.

    "If you cannot grok the overall structure of a program while taking a shower, you are not ready to code it." -- Richard Pattis.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Caesar Cipher
    By dldsob in forum C++ Programming
    Replies: 7
    Last Post: 07-06-2009, 06:06 PM
  2. Caesar Cipher
    By blacknapalm in forum C Programming
    Replies: 8
    Last Post: 11-13-2008, 12:11 AM
  3. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  4. caesar cipher help.
    By stormfront in forum C Programming
    Replies: 36
    Last Post: 11-22-2005, 08:45 PM
  5. Help with Caesar cipher
    By jcmichman in forum C++ Programming
    Replies: 1
    Last Post: 04-05-2005, 10:50 AM