Can't figure out what the error is here

P

Protoman

Can you please help me figure out what the error is here, in this
rotor cipher simulator, which I wrote to amuse myself? The runtime
error is that it isn't symmetrical --decrypting a piece of ciphertext
w/ the encrypting key doesn't result in the original message--, which
I'm assuming is linked to a coding error. I've spent hours pouring
over this code, and I can't find anything. I must be missing
something...something subtle. Here's the code:

Enigma.hpp
-------------------------------
#ifndef ENIGMA_HPP
#define ENIGMA_HPP
#include <iostream>
#include <string>
using namespace std;
class Error{};
class Rotor
{
public:
Rotor(char pos=0):CurPos(0),steps(0)
{
memcpy(Alphabet,"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",36);
SetRotorPosition(CharacterMap(pos));
}
int GetSteps()const{return steps;}
static int CharacterMap(char the_char)
{
static const char *alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const char* p;
if (p=strchr(alphabet, the_char))
return (p-alphabet);
else
throw Error();
}
void SetRotorPosition(int NewPos)
{
while(NewPos < 0)
{
NewPos+=36;
}
CurPos=NewPos%36;
steps=0;
}
void AdvanceRotor(int Steps)
{
CurPos += Steps;
while(CurPos < 0)
{
CurPos +=36;
}
CurPos %=36;
steps+=Steps%36;
}
void ReverseRotor(int Steps)
{
AdvanceRotor(-Steps);
}
char GetCurrentCharacter()const
{
return Alphabet[CurPos];
}
char GetCharacterIndex(int Index)const
{
return Alphabet[(CurPos+Index)%36];
}
char GetCharacterInverse(int i)const
{
if (i>=CurPos)
return Alphabet[i - CurPos];
else
return Alphabet[36 + i - CurPos];
}
private:
char Alphabet[36];
int CurPos;
int steps;
};

class Enigma
{
public:
Enigma(char r1,char r2,char r3,char r4,char r5,char r6,char r7,char
r8,char r9,char r10):
R1(r1),R2(r2),R3(r3),R4(r4),R5(r5),R6(r6),R7(r7),R8(r8),R9(r9),R10(r10)
{
memcpy(Reflector,"COAYIWV7E3809TBUZ26NPGF4DQL5RJX1SHKM",36);
}
~Enigma(){}
string Encrypt(const string& cleartext);
string Decrypt(const string& ciphertext);
private:
char plugboard(char input);
Rotor R1;
Rotor R2;
Rotor R3;
Rotor R4;
Rotor R5;
Rotor R6;
Rotor R7;
Rotor R8;
Rotor R9;
Rotor R10;
char Reflector[36];
};
#endif
-------------------------

Enigma.cpp
-------------------------
#include "Enigma.hpp"
#include <string>
using namespace std;

char Enigma::plugboard(char Char)
{
if(Char=='A')
return '0';
else if(Char=='B')
return 'Q';
else if(Char=='C')
return 'W';
else if(Char=='D')
return 'E';
else if(Char=='E')
return 'D';
else if(Char=='F')
return 'T';
else if(Char=='G')
return 'Y';
else if(Char=='H')
return 'U';
else if(Char=='I')
return 'I';
else if(Char=='J')
return 'O';
else if(Char=='K')
return 'P';
else if(Char=='L')
return 'S';
else if(Char=='M')
return 'N';
else if(Char=='N')
return 'M';
else if(Char=='O')
return 'J';
else if(Char=='P')
return 'K';
else if(Char=='Q')
return 'B';
else if(Char=='R')
return 'Z';
else if(Char=='S')
return 'L';
else if(Char=='T')
return 'F';
else if(Char=='U')
return 'H';
else if(Char=='V')
return 'X';
else if(Char=='W')
return 'C';
else if(Char=='X')
return 'V';
else if(Char=='Y')
return 'G';
else if(Char=='Z')
return 'R';
else if(Char=='0')
return 'A';
else if(Char=='1')
return '9';
else if(Char=='2')
return '8';
else if(Char=='3')
return '7';
else if(Char=='4')
return '6';
else if(Char=='5')
return '5';
else if(Char=='6')
return '4';
else if(Char=='7')
return '3';
else if(Char=='8')
return '2';
else if(Char=='9')
return '1';
}

string Enigma::Encrypt(const string& cleartext)
{
string ciphertext;
ciphertext.resize(cleartext.size());
unsigned int i=0;
for(;i<cleartext.length();i++)
{
int val=Rotor::CharacterMap(plugboard(cleartext));
if (val<36)
{
char val1 = R1.GetCharacterIndex(val);
int val2 = Rotor::CharacterMap(val1);
char val3 = R2.GetCharacterIndex(val2);
int val4 = Rotor::CharacterMap(val3);
char val5 = R3.GetCharacterIndex(val4);
int val6 = Rotor::CharacterMap(val5);
char val7 = R4.GetCharacterIndex(val6);
int val8 = Rotor::CharacterMap(val7);
char val9=R5.GetCharacterIndex(val8);
int val10 = Rotor::CharacterMap(val9);
char val11=R6.GetCharacterIndex(val10);
int val12=Rotor::CharacterMap(val11);
char val13=R7.GetCharacterIndex(val12);
int val14=Rotor::CharacterMap(val13);
char val15=R8.GetCharacterIndex(val14);
int val16=Rotor::CharacterMap(val15);
char val17=R9.GetCharacterIndex(val16);
int val18=Rotor::CharacterMap(val17);
char val19=R10.GetCharacterIndex(val18);
int val20=Rotor::CharacterMap(val19);
char val21 = Enigma::Reflector[val20];
int val22 = Rotor::CharacterMap(val21);
char val23 = R10.GetCharacterInverse(val22);
int val24 = Rotor::CharacterMap(val23);
char val25 = R9.GetCharacterInverse(val24);
int val26 = Rotor::CharacterMap(val25);
char val27 = R8.GetCharacterInverse(val26);
int val28 = Rotor::CharacterMap(val27);
char val29 = R7.GetCharacterInverse(val28);
int val30 = Rotor::CharacterMap(val29);
char val31 = R6.GetCharacterInverse(val30);
int val32=Rotor::CharacterMap(val31);
char val33=R5.GetCharacterIndex(val32);
int val34=Rotor::CharacterMap(val33);
char val35=R4.GetCharacterIndex(val34);
int val36=Rotor::CharacterMap(val35);
char val37=R3.GetCharacterIndex(val36);
int val38=Rotor::CharacterMap(val37);
char val39=R2.GetCharacterIndex(val38);
int val40=Rotor::CharacterMap(val39);
char val41=R1.GetCharacterIndex(val40);
ciphertext = plugboard(val41);
R1.AdvanceRotor(1);
if((R1.GetSteps()%36)==0)
{
R2.AdvanceRotor(1);
if((R2.GetSteps()%36)==0)
{
R3.AdvanceRotor(1);
if((R3.GetSteps()%36)==0)
{
R4.AdvanceRotor(1);
if((R4.GetSteps()%36)==0)
R5.AdvanceRotor(1);
{
if((R5.GetSteps()%36)==0)
R6.AdvanceRotor(1);
{
if((R6.GetSteps()%36)==0)
R7.AdvanceRotor(1);
{
if((R7.GetSteps()%36)==0)
R8.AdvanceRotor(1);
{
if((R8.GetSteps()%36)==0)
R9.AdvanceRotor(1);
{
if((R9.GetSteps()%36)==0)
R10.AdvanceRotor(1);
}
}
}
}
}
}
}
}
}
else ciphertext=cleartext;
}
return ciphertext;
}
---------------------------------------

EnigmaMain.cpp
----------------------------------
#include "Enigma.hpp"
#include <iostream>
#include <string>
using namespace std;
int main()
{
start:
bool mode;
cout << "Encrypt or decrypt?[Encrypt=1|Decrypt=0]: " << endl;
cin >> mode;
try
{
if(mode==1)
{
cout << "Enter the rotor settings: " << endl;
char R1,R2,R3,R4,R5,R6,R7,R8,R9,R10;
cin >> R1 >> R2 >> R3 >> R4 >> R5 >> R6 >> R7 >> R8 >> R9 >> R10;
Enigma encryptor(R1,R2,R3,R4,R5,R6,R7,R8,R9,R10);
cin.ignore(1);
string cleartext;
cout << "Enter cleartext: " << endl;
getline(cin,cleartext);
string ciphertext(encryptor.Encrypt(cleartext));
cout << "Ciphertext: " << ciphertext << endl;
}
if(mode==0)
{
cout << "Enter the rotor settings: " << endl;
char R1,R2,R3,R4,R5,R6,R7,R8,R9,R10;
cin >> R1 >> R2 >> R3 >> R4 >> R5 >> R6 >> R7 >> R8 >> R9 >> R10;
Enigma decryptor(R1,R2,R3,R4,R5,R6,R7,R8,R9,R10);
cin.ignore(1);
string ciphertext;
cout << "Enter ciphertext: " << endl;
getline(cin,ciphertext);
string cleartext(decryptor.Encrypt(ciphertext));
cout << "Cleartext: " << cleartext << endl;
}
goto start;
}
catch(Error& obj)
{
cout << "Error. \a" << endl;
goto start;
}
return 0;
}
 
J

Joel Yliluoma

Can you please help me figure out what the error is here, in this
rotor cipher simulator, which I wrote to amuse myself? The runtime
error is that it isn't symmetrical --decrypting a piece of ciphertext
w/ the encrypting key doesn't result in the original message--, which
I'm assuming is linked to a coding error. I've spent hours pouring
over this code, and I can't find anything. I must be missing
something...something subtle. Here's the code:

Compiles fine for me. I couldn't figure out how to run it, though:

bisqwit@chii:~/en$ ./a.out
Encrypt or decrypt?[Encrypt=1|Decrypt=0]:
1
Enter the rotor settings:
1
fkuu
2
3
4
^C

bisqwit@chii:~/en$ ./a.out
Encrypt or decrypt?[Encrypt=1|Decrypt=0]:
1
Enter the rotor settings:
1 2 3 4 5 6 7 8 9 10
Enter cleartext:
Ciphertext:
Encrypt or decrypt?[Encrypt=1|Decrypt=0]:
^C

bisqwit@chii:~/en$
bisqwit@chii:~/en$ ./a.out
Encrypt or decrypt?[Encrypt=1|Decrypt=0]:
1
Enter the rotor settings:
aiueoaiueo
Error.
Encrypt or decrypt?[Encrypt=1|Decrypt=0]:
^C



So you need to explain.
 
J

Joel Yliluoma

Compiles fine for me. I couldn't figure out how to run it, though:

In any case, I think your question has nothing to do
with C++ language per se.
It's a "find a bug in my program" type question, which may
be better suited for a group such as comp.programming.

However, I find a lot of numbered variables in your code. Are you
sure that an array and a loop won't do?
It could greatly simplify your code and improve your chances
of finding the actual error.
 
R

Richard Heathfield

[Re-crossposted to clc++ for what I hope are (or will become) obvious
reasons, but followups set to comp.programming again]

Joel Yliluoma said:
In any case, I think your question has nothing to do
with C++ language per se.
It's a "find a bug in my program" type question, which may
be better suited for a group such as comp.programming.

The trouble is that comp.programming will now ask "er, find a bug in *what*
program?"
 
G

Guest

Can you please help me figure out what the error is here, in this
rotor cipher simulator, which I wrote to amuse myself? The runtime
error is that it isn't symmetrical --decrypting a piece of ciphertext
w/ the encrypting key doesn't result in the original message--, which
I'm assuming is linked to a coding error.

Most likely it is a logical error, and not a programming error. In other
words you have not created an Enigma cipher, but rather something that
at a first glance looks like it but it does not work like Enigma. Go
through the logic of the program step by step and make sure that it
works like Enigma.

BTW, how secure do you believe this cipher to be, bitwise?

No idea, probably not very secure by today's standards. For a better
answer ask in a cryptography group, such as sci.crypt.
 

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

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top