Encryption doesn't work right

P

Protoman

I'm trying to write an encryption program, and it doesn't produce the
right output; "GOOGLE" encrypted w/"GOOGLE" IS NOT "ee".
Here's the code:

namespace
{
const char vTable[26][27]=
{
{'Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'},
{'W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q'},
{'E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W'},
{'R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E'},
{'T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R'},
{'Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T'},
{'U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y'},
{'I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U'},
{'O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I'},
{'P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O'},
{'A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P'},
{'S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A'},
{'D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S'},
{'F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D'},
{'G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F'},
{'H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G'},
{'J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H'},
{'K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J'},
{'L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K'},
{'Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L'},
{'X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z'},
{'C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X'},
{'V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C'},
{'B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V'},
{'N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B'},
{'M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N'},
};

void convert(string& String)
{
for(int i=0;i<String.length();i++)
String=(toupper(String));
}

string encrypt(const string& cleartext,const string& key)
{
string encrypted;
for(int i=0;i<cleartext.length();i++)
encrypted+=vTable[cleartext-'A'][key[i%key.length()]-'A'];
return encrypted;
}

string decrypt(const string& ciphertext,const string& key)
{
string decrypted;
for(int i=0;i<ciphertext.length();i++)
decrypted+=vTable[key[i%key.length()]-'A'][ciphertext-'A'];
return decrypted;
}
}

int main()
{
try
{
string cleartext;
string key;
cout << "Enter cleartext: ";
getline(cin,cleartext,'\n');
cout << "Enter key: ";
getline(cin,key,'\n');
convert(cleartext);
convert(key);
encrypt(cleartext,key);
cout << "Ciphertext: " << encrypt(cleartext,key)<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
catch(std::exception const& x)
{
std::cerr << "!" << x.what() << std::endl;
return EXIT_FAILURE;
}
}

Any idea as what might be wrong? Thanks!!!
 
I

Ivan Vecerina

Protoman said:
I'm trying to write an encryption program, and it doesn't produce the
right output; "GOOGLE" encrypted w/"GOOGLE" IS NOT "ee".
Here's the code: ....
Any idea as what might be wrong? Thanks!!!
The algorithm you have chosen.

Seriously, what are you trying to implement?
Why do you believe that "GOOGLE" encrypted with "GOOGLE"
is supposed to be "ee" ?

Try an encryption-related newsgroup to first discuss the
algorithm you are trying to implement. Once and if you
narrow-down the issue to a C++ problem, you may want to
come back here and ask a more specific question.


Ivan
 
G

Greg

Protoman said:
I'm trying to write an encryption program, and it doesn't produce the
right output; "GOOGLE" encrypted w/"GOOGLE" IS NOT "ee".
Here's the code:

namespace
{
const char vTable[26][27]=
{
{'Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'},
{'W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q'},
{'E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W'},
{'R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E'},
{'T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R'},
{'Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T'},
{'U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y'},
{'I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U'},
{'O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I'},
{'P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O'},
{'A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P'},
{'S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A'},
{'D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S'},
{'F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D'},
{'G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F'},
{'H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G'},
{'J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H'},
{'K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J'},
{'L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K'},
{'Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L'},
{'X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z'},
{'C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X'},
{'V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C'},
{'B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V'},
{'N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B'},
{'M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N'},
};
....>
Any idea as what might be wrong? Thanks!!!

The problem here is that the table for this Vigenere cipher program no
longer has the nice symmetric layout that allowed for relatively easy
decryption. With this table, the program should now search for the
encoded character along the key's axis. The offset where it is found
will be equivalent to the unencrypted letter:

string decrypt(const string& ciphertext, const string& key)
{
string decrypted;

for (int i=0; i < ciphertext.length();i++)
for (char j = 0; j < 27; j++)
{
// search for encoded char along axis of key char
if (vTable[j] [key[ i % key.length()]-'A']
== ciphertext)
{
decrypted += char(j+'A');
break;
}
}
return decrypted;
}

Greg
 
P

Protoman

Greg said:
Protoman said:
I'm trying to write an encryption program, and it doesn't produce the
right output; "GOOGLE" encrypted w/"GOOGLE" IS NOT "ee".
Here's the code:

namespace
{
const char vTable[26][27]=
{
{'Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'},
{'W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q'},
{'E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W'},
{'R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E'},
{'T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R'},
{'Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T'},
{'U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y'},
{'I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U'},
{'O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I'},
{'P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O'},
{'A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P'},
{'S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A'},
{'D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S'},
{'F','G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D'},
{'G','H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F'},
{'H','J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G'},
{'J','K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H'},
{'K','L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J'},
{'L','Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K'},
{'Z','X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L'},
{'X','C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z'},
{'C','V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X'},
{'V','B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C'},
{'B','N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V'},
{'N','M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B'},
{'M','Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N'},
};
...>
Any idea as what might be wrong? Thanks!!!

The problem here is that the table for this Vigenere cipher program no
longer has the nice symmetric layout that allowed for relatively easy
decryption. With this table, the program should now search for the
encoded character along the key's axis. The offset where it is found
will be equivalent to the unencrypted letter:

string decrypt(const string& ciphertext, const string& key)
{
string decrypted;

for (int i=0; i < ciphertext.length();i++)
for (char j = 0; j < 27; j++)
{
// search for encoded char along axis of key char
if (vTable[j] [key[ i % key.length()]-'A']
== ciphertext)
{
decrypted += char(j+'A');
break;
}
}
return decrypted;
}

Greg


OK, but it still doesn't *encrypt* right; I know b/c I checked it by
hand.
 
B

Bob Hairgrove

if (vTable[j] [key[ i % key.length()]-'A']
== ciphertext)
{
decrypted += char(j+'A');
break;
}


you should be very careful about how your compiler treats character
types: are they signed or unsigned? In C language, a character literal
has type int, which is of course signed; in C++, it has type plain
char which has unspecified sign (WRT the language, i.e. the sign is
"don't care"). Your compiler will probably have a switch to influence
this behavior. In the above statements, when used within an
expression, I believe that char is implicitly converted to int.

Of course, you will only run into problems with this when trying to
encode text with extended characters; but even in the English
language, they can pop up unexpectedly -- for example, text with
symbols such as '£' or the various typographical quote signs which
MS-Word is so fond of using (and which never display properly in my
browser...), or the Euro sign. These will suddenly appear as negative
values if char is treated as signed.
 
K

Karl Heinz Buchegger

Protoman said:
OK, but it still doesn't *encrypt* right; I know b/c I checked it by
hand.

Fine. Now do the very same with your program: That is called debugging.

PS: You might want to 'enhence' your program such that the program helps
you to figure out where you programmed it in a wrong way. Eg.

Your function:
string encrypt(const string& cleartext,const string& key)
{
string encrypted;
for(int i=0;i<cleartext.length();i++)
encrypted+=vTable[cleartext-'A'][key[i%key.length()]-'A'];
return encrypted;
}


I suggest now to 'enhance' it:

string encrypt(const string& cleartext,const string& key)
{
string encrypted;

for( int i = 0; i < cleartext.length(); i++ ) {

cout << "i: " << i << endl;
cout << "Cleartext[" << i << "]" << cleartext << endl;
cout << "-> " << (int)( cleartext-'A' ) << endl;
cout << "Key[" << i%key.length() << "]" << key[i%key.length()] << endl;
cout << "-> " << (int)( key[i%key.length()]-'A' ) << endl;
cout << "Table: " << vTable[cleartext-'A'][key[i%key.length()]-'A'] << endl;

encrypted += vTable [ cleartext - 'A' ] [ key[i%key.length() ] - 'A' ];
}

return encrypted;
}

That is: All I did was to introduce output statements showing some important
values in the encryption process. Run the program, let it do the same encryption
you did on paper and figure out where your programs behaviour differed from the
one you did on paper. Then draw your conclusions from that analysis and fix your
program. Once it runs as expected, remove (or comment out) the additional code.

(Also note how a little bit of white space at strategic places added a lot to
the readability of the function).
 
G

Greg

Protoman said:
Greg said:
Protoman said:
I'm trying to write an encryption program, and it doesn't produce the
right output; "GOOGLE" encrypted w/"GOOGLE" IS NOT "ee".
Here's the code:

namespace
{
const char vTable[26][27]=
{
{'Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'},
{'W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M','Q'},

Note that vTable really should by 26 by 26, not 27.
OK, but it still doesn't *encrypt* right; I know b/c I checked it by
hand.

I would check again. It's unlikely decryption would be working if
encryption were broken. It's more likely that your hand encryption
differs somehow from the program's.

When encrypting by hand, the letter from the key is used as the
horizontal axis across the top of the table to select the appropriate
column. The plaintext letter is then used to go down the rows of that
column to select the encrypted letter. For example: given plaintext
GOOGLE and password PASS, the first encrypted letter is the 16th column
('P' is the 16th letter of the alphabet) and 7 rows down ('G' is 7th)
to find the encrypted letter 'C'. Doing the same with the other letters
yields the ciphertext: CGUNQT.

To decrypt the first letter, use the key to find the horizontal access
(it will be the same column that was used to encrypt that lettter) and
then count down the rows until the encrypted letter is found. How ever
many rows down the letter was found will be the unecrypted letter's
position in the alphabet. For example, to decrypt 'C' with the key
letter being 'P', use the key to find the 16th column. Count down the
rows until 'C' is found at the 7th row. The 7th letter of the alphabet
is G, so the first unecrypted letter of CGUNQT with password PASS is G.
Decrypting the rest yields the entire plaintext: GOOGLE.

Greg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top