Thread: Encryption and Decryption Program in C++ using a class

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Encryption and Decryption Program in C++ using a class

    Hi everyone,

    I have gotten most of a encryption and decryption part of a C++ program to work but I am having problems with wrapping around the alphabet and I am getting weird characters for the encryption and decryption whenever I enter spaces in a line of text.

    I have a program where the key code is 4. For example, if the user enters a line of text called "Hello World", it would then be ENCRYPTED as "Lipps Asvph" where letter in the alphabet increases by 4 letters where H becomes L, e becomes i and so on.

    Here are the two problems I am having with this program:

    The letter W (in the "Hello World" example) should wrap around to the beginning of the alphabet and become letter A but instead I am getting a weird character and not the letter A in my output. I am also getting weird characters in output anytime the user enters spaces in between words in the text line. These are the two problems that I want to correct.

    Here is my code so far:

    Code:
    #include <iostream>
    #include <string>
    #include <conio.h>
    
    class Encrypt {
    
       private:
          char line[80];
          int key;
    
       public:
          void getdata();
          void enc();
          void dec();
          void mix();
    
    };
    
    void Encrypt::getdata() {
       cout <<"Enter a line of text: ";
       cin.getline(line, 80);
    }
    
    void Encrypt::enc() {
       int code;
       int length;
       char *enc;
       key = 4;
       enc = line;
       length = strlen(line);
    
       for (int i = 0; i < length; i++) {
          *enc += key;
          enc++;
       }
       cout << "Encrypted text is: " << line << endl;
    }
    
    void Encrypt::dec() {
       int length;
       char *dec;
       key = 4;
       dec = line;
       length = strlen(line);
    
       for (int i = 0; i < length; i++) {
          *dec -= key;
          dec++;
       }
       cout << "Decrypted text is: " << line << endl;
       getche();
    }
    
    int main() {
       Encrypt text;
       text.getdata();
       text.enc();
       text.dec();
    }
    The first problem is that I can't get it to wrap around from the end to the beginning of the alphabet for encryption (Letter W to Letter A when key = 4) and vice versa (Letter A to Letter W) for decryption.

    If anyone has any suggestions or advice for me on how to correct these two problems, it would be greatly appreciated.

    Thanks.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    @ the weird character problem:

    Your character set consists of more than just the latin alphabet. There are characters before, after, and possibly even between the ones that you want. So you need to force the program to do what you want it to do by doing it manually:
    Code:
    #include <iostream>
    
    int main()
    {
      const char *letters = "abcdefghijklmnopqrstuvwxyz";
    
      for ( int i = 0; i < 100; i++ )
        std::cout << letters[i % 26] << ' ';
    }
    @ the whitespace problem:

    Ignore whitespace with isspace(), declared in <cctype>.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Nov 2004
    Posts
    73
    Thanks for the advice Prelude. I'll see if what you said will fix those issues.

    I'm still looking for some help on how to wrap to the beginning of the alphabet where for example in encryption letter Y would become letter C with a key of 4 going from Y to Z to A to B and resting at C. That's a tricky part.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I'm still looking for some help on how to wrap to the beginning of the alphabet
    Reread my post and try the code. That's your wrapping solution.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Nov 2004
    Posts
    73

    Re:

    I'm having a hard time understanding how the code you posted works Prelude but I'll try it out tomorrow when I have more time.

    Thanks.

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    1)You don't have any constructors for your class? I think you should have a constructor that asks for the string and sets the key. That's what constructors are for--initializing data members.

    2) What's the purpose of this line:

    enc = line;

    3) You have to check each character you are encrypting to see whether the 4 character shift has gone beyond the end of the alphabet. Where do you check for that?
    Code:
    for (int i = 0; i < length; i++) {
          *enc += key;
          enc++;
      }
    When you add 4 to a character, you are adding 4 to what's called its "ascii code". ascii codes are numerical synonyms for characters. A computer can only store numbers--it has no idea what a character is. So, there are numerical ascii codes assigned to each character so that you can store them on a computer. Try this:
    Code:
    char ch = 'a';
    int myVar = ch;
    cout<<myVar<<endl;
    The number you see displayed is the ascii code for the character 'a'. The ascii codes for capital letters run from 65-88 and the ascii codes for the lower case letters run from 97-122. A char type actually stores an integer value, i.e an ascii code, but when you try to display a char variable, the integer is automatically converted to the corresponding character. If you assign a char variable to an integer variable, the integer value stored in the char variable is copied into the integer variable; and when you display an integer variable, no character conversion takes place. A char type tells the compiler that the integer stored in the variable is actually an ascii code and therefore it should be converted to a character when displayed.

    The result is if you do this:
    Code:
    char ch = 97;
    int n = 97;
    cout<<ch<<endl;
    cout<<n<<endl;
    the character 'a' will be displayed in the first case, and the number 97 will be displayed in the second case.

    In your program, when you add 4 to a character's ascii code and the result is a number higher than 122, you have gone past the end of the alphabet. The characters just past the end of the alphabet are '{', '}', |, ~, and delete. What you need to do is check each character to see if adding 4 to it yields a number higher than 122. If so, you need to wrap around. How can you check to see if a char is higher than 122? You can use an if statement like this:

    if(line[i]>122)...

    or like this:

    if(line[i] > 'z')

    If the code is higer than 122, you can use the remainder(or modulus) operator to find out how much greater than 122 like this:

    int wrap = line[i]%122;

    Then, you can add wrap to 65( = 'A') to get your encrypted char. However, you are going to run into problems. Once again, the letters of the alphabet have the ascii codes:

    caps: 65-88
    lowercase: 97-122

    What if you add 4 to a capital 'Z'(= 88)? You will get an ascii code of 92, which is not a letter of the alphabet. Looking at an ascii table, 92 is the character '\'. So, you not only have to wrap, you have to "leap" over the ascii codes that aren't letters in the alphabet.

    Of course, you don't have to use only letters of the alphabet, but if that is what you want to do, then Prelude posted a possible solution:

    1) Set up a string or a cstring with all the letters you want to use for your encryption.

    2) Get a letter from the string you want to encode.

    3) Assign the letter to an int var to get it's ascii code(necessary because of step 5)

    4) Add 4 to the ascii code.

    5) Use the result in 4 as the index position for the letter you will obtain from the encryption string in 1), e.g.:

    encryption_string[resultCode]

    Ok, but you are still left with the problem of wrapping (but now you don't have to worry about leaping). That can be solved as discussed above with an if statement or the remainder operator. If you use the lower case letters of the alphabet as your encryption string, then the index positions of that string will run from 0-25 (there are 26 letters in the alphabet). Now, as a first pass you might think of using:

    encryption_string[resultCode % 25]

    but if the resultCode is 25, then resultCode%25 will be equal to 0, so you will have wrapped too early and you won't ever select index position 25, which is the 'z'. So, you want to wrap when the resultCode has gone one past the end of the encryption string or when resultCode is 26. That gives you:

    encryption_string[resultCode % 26]

    If resultCode is 25, then 25 % 26 is 25, and if resultCode is 26, then 26 % 26 is 0, so you will have wrapped back to index position 0. That means your possible index positions will run from 0-25 which are all the possible index positions in the encryption string.
    Last edited by 7stud; 06-04-2005 at 01:10 PM.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I'm having a hard time understanding how the code you posted works Prelude
    Okay, let's go with something roughly equivalent that I find easier to understand for more complicated cases:
    Code:
    #include <iostream>
    
    int main()
    {
      const char *letters = "abcdefghijklmnopqrstuvwxyz";
      int j = 0;
    
      for ( int i = 0; i < 100; i++ ) {
        if ( j == 26 )
          j = 0;
        std::cout << letters[j++] << ' ';
      }
    }
    The trick is twofold. First, you define the range and members of your set of data, in this case the 26 letters of the latin alphabet. Then you loop around and around that set by starting over at the beginning when you reach the end, thus the part that says:
    Code:
    if ( j == 26 )
      j = 0;
    However, because j keeps getting reset to 0, it can no longer be a decent counter for the loop, so now we have both i to count the loop and j to index the string. Both i and j are incremented with every iteration of the loop.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Nov 2004
    Posts
    73
    Thanks for your post 7stud! I just read it now and things make a lot more sense and to answer your questions:

    1. Yes, I probably will eventually create a constructor to initialize the key to 4.

    2. the enc = line just told the pointer to point to the beginning of the line of text

    3. I didn't check the wrapping at all because I hadn't gotten that far yet and that is where I was stuck

    So basically I should revamp this and check everything using ASCII code.

    Would I still need to use a pointer such as *enc to move to the next letter in the string of text?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. encryption / decryption program
    By epidemic in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2008, 06:40 AM
  2. Advice on writing a basic encryption program?
    By osiris^ in forum C Programming
    Replies: 2
    Last Post: 09-10-2007, 02:02 PM
  3. Problem with basic encryption program.
    By mmongoose in forum C++ Programming
    Replies: 5
    Last Post: 08-27-2005, 04:41 AM
  4. Ask about Encryption and Decryption
    By ooosawaddee3 in forum C Programming
    Replies: 3
    Last Post: 07-19-2002, 12:55 AM
  5. Data Encryption Program
    By Dragonlord in forum C++ Programming
    Replies: 2
    Last Post: 01-01-2002, 04:41 AM