Any way to make this code more compact, and/or be able to change at runtime?

P

Protoman

I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

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';
}

If you need any more info, just ask and I'll produce it. Thanks!!!!
 
R

Robert Bauck Hamar

Protoman said:
I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

In this situation, a switch might be more compact:

switch (Char) {
case 'A': return '0';
case 'B': return 'Q';
....
}

If you want to change at runtime:
#include <map>

class Enigma {
std::map<char, char> plug;
public:
char plugboard(char Char) {
return plug[Char];
}
....
};
 
P

Protoman

Protoman said:
I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

In this situation, a switch might be more compact:

switch (Char) {
case 'A': return '0';
case 'B': return 'Q';
...

}

If you want to change at runtime:
#include <map>

class Enigma {
std::map<char, char> plug;
public:
char plugboard(char Char) {
return plug[Char];
}
...

};

Oh, and the encrypt() doesn't work right...it just returns the first
char of the cleartext:

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);
}
}
}
}
}
}
}
} // problem #2 missing brace
else {ciphertext = cleartext;}
}
return ciphertext;
}
}
 
S

Scott McPhillips [MVP]

Protoman said:
I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

char Enigma::plugboard(char Char)
{
if(Char=='A')
return '0';
else if(Char=='B')
return 'Q';
....

Put all the outputs in a char array[] = {'0', 'Q', ...};
return array[Char - 'A'];

To change the mapping at run time you could read a file into the array.
 
J

Jim Langston

Protoman said:
I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

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';
}

If you need any more info, just ask and I'll produce it. Thanks!!!!

I can think of a few ways to do it more compact. a std::map would be one
way, although you'd still have to add the members to the map. I think it
depends on what is your primary concern, speed of execution or
maintanability. One simple thing, however, is that you only have the
letters 'A' through 'Z' and the digits '0' through '9'.

Consider something like the following (untested bug ridden) code:

char Enigma::plugboard(char Char)
{
char Vallues* = "0QWEDTYU'I'OPSNMJKBZLFHXCVGRA987654321"
if ( Char >= 'A' && Char <= 'Z' )
return Values[Char - 'A'];
else if ( Char >= '0' && Char <= '0' )
return Values[ 26 + Char - '0' ];
else
return 0;
)

However, this will only work on platforms where 'A' through 'Z' and '0'
through '9' are contiguous (ASCII, wouldn't work in EBSIDIC (sp?) ).
You can also create an array to find the postion:
char Characters* = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
so find the Char in Characters, get it's postion, return Values[Position];

Now, this is more compact, and you can change what Values points at (make it
array, pass in a pointer, whatever).
 
P

Protoman

Protoman said:
I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?
char Enigma::plugboard(char Char)
{
if(Char=='A')
return '0';
else if(Char=='B')
return 'Q';

...

Put all the outputs in a char array[] = {'0', 'Q', ...};
return array[Char - 'A'];

To change the mapping at run time you could read a file into the array.

OK, did that, but:

1. How do I get it to be able be changed w/ a text file, and
2. What's wrong w/ Encrypt()?

Thanks!!!
 
S

Sarath

I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

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';

}

If you need any more info, just ask and I'll produce it. Thanks!!!!

If your routine has definite algorithm, it's better to to return the
values with some mathematical expressions that would be better.

I've managed to optimize your problems as follows with look-up table.

See the sample snippet below. Hope you can understand my code. I'm not
explaining it :)

// Look up table
const char buff[] =
{
'0','Q','W','E','D','T','Y','U','I','O','P','S',
'N','M','J','K','B','Z','L','F','H','X','C','V',
'G','R','A','9','8','7','6','5','4','3','2','1'
};

char Plugboard(char Char)
{
// Check the ASCII Table for the values
if( Char >= 48 && Char <= 57 )// '0' to '9' range validating
return buff[Char-48+26];
else if( Char >= 65 && Char <= 90 ) // 'A' to 'Z' range validating
return buff[Char-65];
else
return '\0';

}

int main(int argc, char* argv[])
{
cout<<Plugboard( 'R' );
return 0;
}

HTH

Regards,
Sarath
http://sarathc.wordpress.com/
 
J

Jim Langston

Sarath said:
I've written this program that simulates a 36 character, 10 rotor
reciprocal rotor cipher, w/ a plugboard. Any way I can make the
plugboard function more compact and/or be able to change the mapping
at runtime?

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';

}

If you need any more info, just ask and I'll produce it. Thanks!!!!

If your routine has definite algorithm, it's better to to return the
values with some mathematical expressions that would be better.

I've managed to optimize your problems as follows with look-up table.

See the sample snippet below. Hope you can understand my code. I'm not
explaining it :)

// Look up table
const char buff[] =
{
'0','Q','W','E','D','T','Y','U','I','O','P','S',
'N','M','J','K','B','Z','L','F','H','X','C','V',
'G','R','A','9','8','7','6','5','4','3','2','1'
};

char Plugboard(char Char)
{
// Check the ASCII Table for the values
if( Char >= 48 && Char <= 57 )// '0' to '9' range validating
return buff[Char-48+26];

Just a comment on style,
if ( Char >= '0' && Char <= '9' )
return buff[char - '0' + 26];

48 and '0' are equal, and self documenting (in ASCII). Same with below.
else if( Char >= 65 && Char <= 90 ) // 'A' to 'Z' range validating
return buff[Char-65];
else
return '\0';

}

int main(int argc, char* argv[])
{
cout<<Plugboard( 'R' );
return 0;
}

HTH

Regards,
Sarath
http://sarathc.wordpress.com/
 
B

BobR

Jim Langston wrote in message...
Protoman said:
char Enigma::plugboard(char Char){
}
If you need any more info, just ask and I'll produce it. Thanks!!!!

I can think of a few ways to do it more compact. a std::map would be one
way, although you'd still have to add the members to the map. I think it
depends on what is your primary concern, speed of execution or
maintanability. One simple thing, however, is that you only have the
letters 'A' through 'Z' and the digits '0' through '9'.

Consider something like the following (untested bug ridden) code:

char Enigma::plugboard(char Char)
{
char Vallues* = "0QWEDTYU'I'OPSNMJKBZLFHXCVGRA987654321"
if ( Char >= 'A' && Char <= 'Z' )
return Values[Char - 'A'];
else if ( Char >= '0' && Char <= '0' )
return Values[ 26 + Char - '0' ];
else
return 0;
)

However, this will only work on platforms where 'A' through 'Z' and '0'
through '9' are contiguous (ASCII, wouldn't work in EBSIDIC (sp?) ).
You can also create an array to find the postion:
char Characters* = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
so find the Char in Characters, get it's postion, return Values[Position];

Now, this is more compact, and you can change what Values points at (make it
array, pass in a pointer, whatever).

Take it a step further, maybe:

char plugboard( char Char ){
std::string Values
( "0QWEDTYUIOPSNMJKBZLFHXCVGRA987654321" );
std::string Characters
( "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" );
std::size_t index( Characters.find( Char ) );
if( std::string::npos == index ){ return ' ';}
return Values.at( index );
} // plugboard(char)

{ // main or ?
std::string Vals( "NOWISTHETIMEFOR2007" );
// std::string Vals( "NOW IS THE TIME FOR 2007" );
std::cout<<"Vals:\n"<<Vals<<std::endl;
for( std::size_t i(0); i < Vals.size(); ++i){
std::cout<< plugboard( Vals.at(i) );
}
} // main()
/* Vals:
NOWISTHETIMEFOR2007
MJCILFUDFINDTJZ8AA3

NOW IS THE TIME FOR 2007
MJC IL FUD FIND TJZ 8AA3
*/
 
P

Protoman

Jim Langston wrote in message...
I can think of a few ways to do it more compact. a std::map would be one
way, although you'd still have to add the members to the map. I think it
depends on what is your primary concern, speed of execution or
maintanability. One simple thing, however, is that you only have the
letters 'A' through 'Z' and the digits '0' through '9'.
Consider something like the following (untested bug ridden) code:
char Enigma::plugboard(char Char)
{
char Vallues* = "0QWEDTYU'I'OPSNMJKBZLFHXCVGRA987654321"
if ( Char >= 'A' && Char <= 'Z' )
return Values[Char - 'A'];
else if ( Char >= '0' && Char <= '0' )
return Values[ 26 + Char - '0' ];
else
return 0;
)
However, this will only work on platforms where 'A' through 'Z' and '0'
through '9' are contiguous (ASCII, wouldn't work in EBSIDIC (sp?) ).
You can also create an array to find the postion:
char Characters* = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
so find the Char in Characters, get it's postion, return Values[Position];
Now, this is more compact, and you can change what Values points at (make it
array, pass in a pointer, whatever).

Take it a step further, maybe:

char plugboard( char Char ){
std::string Values
( "0QWEDTYUIOPSNMJKBZLFHXCVGRA987654321" );
std::string Characters
( "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" );
std::size_t index( Characters.find( Char ) );
if( std::string::npos == index ){ return ' ';}
return Values.at( index );
} // plugboard(char)

{ // main or ?
std::string Vals( "NOWISTHETIMEFOR2007" );
// std::string Vals( "NOW IS THE TIME FOR 2007" );
std::cout<<"Vals:\n"<<Vals<<std::endl;
for( std::size_t i(0); i < Vals.size(); ++i){
std::cout<< plugboard( Vals.at(i) );
}
} // main()
/* Vals:
NOWISTHETIMEFOR2007
MJCILFUDFINDTJZ8AA3

NOW IS THE TIME FOR 2007
MJC IL FUD FIND TJZ 8AA3
*/

--
Bob R
POVrookie- Hide quoted text -

- Show quoted text -

OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext.
 
B

BobR

Protoman said:
OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext.

And you could probably get help with that IF you provide enough code, and
give a clear explanation of what it is doing/not doing. Format your code
(indent (NO tabs)) so we can read it.

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);

What is 'Rotor::CharacterMap()'?
What is 'R1.GetCharacterIndex()'?
.... etc.
 
P

Protoman

Protoman said:
OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext.

And you could probably get help with that IF you provide enough code, and
give a clear explanation of what it is doing/not doing. Format your code
(indent (NO tabs)) so we can read it.

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);

What is 'Rotor::CharacterMap()'?
What is 'R1.GetCharacterIndex()'?
... etc.


OK, here's the complete files:

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 plugboard);
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)
{
char array[]="ZAQ1XSW2CDE3VFR4BGT5NHY6MJU7KI8LO9P0";
return array[Char-'A'];
}

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);
}
}
}
}
}
}
}
} // problem #2 missing brace
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;
}
 
T

Thomas J. Gritzan

Protoman said:
OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext. [...]
string Enigma::Encrypt(const string& cleartext)
{
string ciphertext;
ciphertext.resize(cleartext.size());
unsigned int i=0;
for(;i<cleartext.length();i++)
{ [...code snipped...]
return ciphertext;
}
} [...]
Now do you guys have enough info to help me? Thanks!!!!

I can't see through your __missing indentation__, but is this
return-statement really inside the for-loop body? That would explain, why
the function returns the first letter only: The loop body only gets
executed once.
 
P

Protoman

Protoman said:
OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext. [...]
string Enigma::Encrypt(const string& cleartext)
{
string ciphertext;
ciphertext.resize(cleartext.size());
unsigned int i=0;
for(;i<cleartext.length();i++)
{

[...code snipped...]
return ciphertext;
}
} [...]
Now do you guys have enough info to help me? Thanks!!!!

I can't see through your __missing indentation__, but is this
return-statement really inside the for-loop body? That would explain, why
the function returns the first letter only: The loop body only gets
executed once.

Oh yeah! Thanks!!!!
 
P

Protoman

Protoman said:
OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext. [...]
string Enigma::Encrypt(const string& cleartext)
{
string ciphertext;
ciphertext.resize(cleartext.size());
unsigned int i=0;
for(;i<cleartext.length();i++)
{

[...code snipped...]
return ciphertext;
}
} [...]
Now do you guys have enough info to help me? Thanks!!!!

I can't see through your __missing indentation__, but is this
return-statement really inside the for-loop body? That would explain, why
the function returns the first letter only: The loop body only gets
executed once.

OK, now it just returns the cleartext.
 
P

Protoman

Protoman said:
OK ,but a couple posts ago, I said the Encrypt() isn't working right;
it only returns the first letter of the cleartext. [...]
string Enigma::Encrypt(const string& cleartext)
{
string ciphertext;
ciphertext.resize(cleartext.size());
unsigned int i=0;
for(;i<cleartext.length();i++)
{
[...code snipped...]
return ciphertext;
}
} [...]
Now do you guys have enough info to help me? Thanks!!!!
I can't see through your __missing indentation__, but is this
return-statement really inside the for-loop body? That would explain, why
the function returns the first letter only: The loop body only gets
executed once.

OK, now it just returns the cleartext.- Hide quoted text -

- Show quoted text -

OK, I think the problem's in plugboard():

char Enigma::plugboard(char Char)
{
char array[]="ZAQ1XSW2CDE3VFR4BGT5NHY6MJU7KI8LO9P0";
return array[Char-'A'];
}
 
B

BobR

Protoman said:
OK, now it just returns the cleartext.- Hide quoted text -
- Show quoted text -

OK, I think the problem's in plugboard():

char Enigma::plugboard(char Char){
char array[]="ZAQ1XSW2CDE3VFR4BGT5NHY6MJU7KI8LO9P0";
return array[Char-'A'];
}

std::cout<<"0="<<int('0')<<std::endl; // that's an zero
std::cout<<"A="<<int('A')<<std::endl;
/* -out- (note: may get different results on other systems.)
0=48
A=65
*/
Don't you see a problem with that?
return array[ -17 ]; // really think that will work?

See my first post in this thread!
( which, BTW, works in both directions.)
{
std::string Vals( "NOW IS THE TIME FOR 2007" );
std::string Back;
std::cout<<"Vals:\n"<<Vals<<std::endl;
for( std::size_t i(0); i < Vals.size(); ++i){
Back.push_back( plugboard( Vals.at(i) ) );
std::cout<< plugboard( Vals.at(i) );
}
std::cout<<"\nVals Back:\n"<<Back<<std::endl;
for( std::size_t i(0); i < Back.size(); ++i){
std::cout<< plugboard( Back.at(i) );
}
}
/* Vals:
NOW IS THE TIME FOR 2007
MJC IL FUD FIND TJZ 8AA3
Vals Back:
MJC IL FUD FIND TJZ 8AA3
NOW IS THE TIME FOR 2007
*/

Why don't you TRY things that people show you?
 
P

Protoman

OK, I think the problem's in plugboard():
char Enigma::plugboard(char Char){
char array[]="ZAQ1XSW2CDE3VFR4BGT5NHY6MJU7KI8LO9P0";
return array[Char-'A'];
}

std::cout<<"0="<<int('0')<<std::endl; // that's an zero
std::cout<<"A="<<int('A')<<std::endl;
/* -out- (note: may get different results on other systems.)
0=48
A=65
*/
Don't you see a problem with that?
return array[ -17 ]; // really think that will work?

See my first post in this thread!
( which, BTW, works in both directions.)
{
std::string Vals( "NOW IS THE TIME FOR 2007" );
std::string Back;
std::cout<<"Vals:\n"<<Vals<<std::endl;
for( std::size_t i(0); i < Vals.size(); ++i){
Back.push_back( plugboard( Vals.at(i) ) );
std::cout<< plugboard( Vals.at(i) );
}
std::cout<<"\nVals Back:\n"<<Back<<std::endl;
for( std::size_t i(0); i < Back.size(); ++i){
std::cout<< plugboard( Back.at(i) );
}}

/* Vals:
NOW IS THE TIME FOR 2007
MJC IL FUD FIND TJZ 8AA3
Vals Back:
MJC IL FUD FIND TJZ 8AA3
NOW IS THE TIME FOR 2007
*/

Why don't you TRY things that people show you?

B/c I want something simpler than that.
 
B

BobR

Protoman wrote in message...
B/c I want something simpler than that.

Simpler than a five line character translator? Good luck with that.
Actually, it's only a three line function if you pass in the string refs.

char plugboard( char Char, std::string const &Values,
std::string const &Characters ){
std::size_t index( Characters.find( Char ) );
if( std::string::npos == index ){ return ' ';}
return Values.at( index );
}

Even at five lines, it's much better than your original 35 (or two liner
that does not work), and it's easier to change the translations.
(hint: std::vector<std::string> TransTables; plugboard( 'Q',
TransTables.at(5), TransTables.at(0) ) ).
 
P

Protoman

Protoman wrote in message...


Simpler than a five line character translator? Good luck with that.
Actually, it's only a three line function if you pass in the string refs.

char plugboard( char Char, std::string const &Values,
std::string const &Characters ){
std::size_t index( Characters.find( Char ) );
if( std::string::npos == index ){ return ' ';}
return Values.at( index );
}

Even at five lines, it's much better than your original 35 (or two liner
that does not work), and it's easier to change the translations.
(hint: std::vector<std::string> TransTables; plugboard( 'Q',
TransTables.at(5), TransTables.at(0) ) ).

But what do I do w/ the two other parameters in the fn?
 

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,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top