Rot13 and Rotation Encryption

I'm having issue with my method for character rotation. I think the issue is that when I try and rotate a character above 'z', I can't rotate it back to the start of 'a' again. my output confirms this problem with characters that moved beyond 'z' but works for those that had not. the passed parameter contains the amount of times the character should be shifted over. both nfile and efile are defined inside my class structure so those should be fine. I'm also not concerned with capital letters as my professor stated to use the tolower call.

I'd appreciate your help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 //----------------------------------------------------------------
void Security::encFileUsingRot(int rotnum) //The rotation number |
{ //Encrypts the file using rotation 9-20-13                     |
  ifstream fin; //                                               |
  ofstream fout; //                                              |
  string filename; //File to be encrypted                        |
  char c; //The individual letter of the word                    |
  string encword; //The encrypted word                           |
  string word; //The original word                               |
//----------------------------------------------------------------
  cout << "What is the name of the file to be encrypted?: ";
  cin >> filename;
  fin.open(filename.data());
  fout.open("encrypt01.txt");
  while (fin >> word)
    {
      nfile.push_back(word);
    }
  rotnum = rotnum % 26; //removes excess spins
  for (int i = 0; i < nfile.size(); i++)
    {
      encword = nfile[i];
      for (int j = 0; j < encword.size(); j++)
        {
          c = encword[j];
          c = tolower(c);
          if ((c < 'a')||(c > 'z')) //Checks if it is a character.
            {
              encword[j] = c;
            }
          else
            {
              c = c + rotnum; //Rotates the word
              if (c > 'z') //If over rotated correct it BUT doesn't work?
                {
                 c = c - 'a';
                }
              encword[j] = c;
            }
        }
      efile.push_back(encword);
      fout << efile[i] << " ";
    }
  fin.close();
  fout.close();
  return;
}
Last edited on
http://www.cplusplus.com/doc/ascii/

According to the above, the ASCII code of 'a' is 0x61 (97), and of 'z' is 0x7A (122).
So let's say you rotate to 124 which is beyond 'z'. The result should be 'b' (98).

To get to the "correct" new value you do 'a' + (124 - 'z' - 1).

x = 'a' + 124 - 'z' - 1
x = 97 + 124 - 122 - 1
x = 98


34
35
36
37
              if (c > 'z') //If over rotated correct it BUT doesn't work?
                {
                 c = 'a' + c - 'z' - 1;
                }


I've said it before in other threads and I will say it for as long as I need to:

ASCII arithmetic hackery is very lacking in elegance! Using this technique makes the code harder to understand and prone to errors.

A more elegant way is to use alphabets strings for substituting. Both strings start with the content "abcd...z", then you rotate the second one by rotnum preferably using the function std::rotate().

alpha1 = "abcdefghijklmnopqrstuvwxyz"
alpha2 = "hijklmnopqrstuvwxyzabcdefg" // for rotnum == 7


After that you simply search for letters in the first, and use the index you found in the second.

Encrypt 'h': position in alpha1 is 7 (counting from 0).
Result: alpha2[7] = 'o'
I think the specific issue with this line of code:
 
    if (c > 'z') //If over rotated correct it BUT doesn't work? 

is the same as in a previous thread.

That is, a char is being treated as a signed 8-bit value in the range -128 to +127. Any value greater than 127 rolls over to a negative number.

Try using unsigned char instead, this will interpret the value as a number in the range 0 to 255.

See previous thread with similar problem on same topic:
http://www.cplusplus.com/forum/beginner/111806/#msg610776

And yes, I do think the suggestion from Catfish4 is a sensible one. For various reasons, not least the fact that not all C++ programs will be running on machines which use the ASCII code.
Last edited on
Topic archived. No new replies allowed.