Solution
/* Programmer: Jennifer Leopold Date: September 18, 2015
File: hw4.cpp
Purpose: Simulate processing of a message through a
simplified Enigma machine containing 3 "inter-
changeable" rotors.
To compile: fg++ hw4.cpp -o hw4
To execute: ./hw4
*/
#include <iostream>
using namespace std;
int main()
{
const short ROTOR_NUM_START = 1; // range of valid rotor
const short ROTOR_NUM_END = 3; // numbers
const char END_OF_MESSAGE_CHAR = '.'; // signals end of msg
const char WORD_DELIMITER = '_'; // delimits 2 words in msg
const short NUM_LETTERS = 26; // # letters in alphabet
const short ASCII_A = 65; // ASCII value of 'A'
short leftRotor, middleRotor, // order that rotors should be
rightRotor; // applied
short whichRotor; // rotor currently being processed
char encryptedChar; // encrypted char (user input)
bool invalidInput; // used when validating user input
// Greeting
cout << "Ready to decrypt message...\n\n";
// Get input for order that the 3 rotors should be applied
do
{
cout << "Enter leftmost rotor number: ";
cin >> leftRotor;
invalidInput = (leftRotor < ROTOR_NUM_START) ||
(leftRotor > ROTOR_NUM_END);
if (invalidInput)
cout << "Leftmost rotor must be between "
<< ROTOR_NUM_START << " and "
<< ROTOR_NUM_END << " (inclusive)!\n";
} while (invalidInput);
do
{
cout << "\nEnter middle rotor number: ";
cin >> middleRotor;
invalidInput = (middleRotor < ROTOR_NUM_START) ||
(middleRotor > ROTOR_NUM_END) ||
(middleRotor == leftRotor);
if (invalidInput)
cout << "Middle rotor must be between "
<< ROTOR_NUM_START << " and "
<< ROTOR_NUM_END << " (inclusive),\n"
<< "and not the same as the leftmost rotor "
<< "(which is " << leftRotor << ")!\n";
} while (invalidInput);
do
{
cout << "\nEnter rightmost rotor number: ";
cin >> rightRotor;
invalidInput = (rightRotor < ROTOR_NUM_START) ||
(rightRotor > ROTOR_NUM_END) ||
(rightRotor == leftRotor) ||
(rightRotor == middleRotor);
if (invalidInput)
cout << "Right rotor must be between "
<< ROTOR_NUM_START << " and "
<< ROTOR_NUM_END << " (inclusive),\n"
<< "and not the same as the leftmost rotor "
<< "(which is " << leftRotor << ") "
<< "\nor the middle rotor (which is "
<< middleRotor << ")!\n";
} while (invalidInput);
cout << endl;
// Get each char in message (until END_OF_MESSAGE_CHAR input)
// and output the decrypted char
do
{
do
{
cout << "Enter character ('A'..'Z', '_', or '.'): ";
cin >> encryptedChar;
invalidInput = ((encryptedChar < 'A') ||
(encryptedChar > 'Z')) &&
((encryptedChar != '.') &&
(encryptedChar != '_'));
if (invalidInput)
cout << "Invalid character entered!\n";
} while (invalidInput);
if (encryptedChar != END_OF_MESSAGE_CHAR)
{
if (encryptedChar != WORD_DELIMITER)
{
cout << "\033[F" << encryptedChar << " -> ";
// Process the char through each of the 3 rotors
for (short rotorNum = 1; rotorNum <= 3; rotorNum++)
{
// Figure out which rotor we're working on
switch (rotorNum)
{
case 1 : whichRotor = leftRotor; break;
case 2 : whichRotor = middleRotor; break;
case 3 : whichRotor = rightRotor; break;
}
// Do the processing for that rotor
switch (whichRotor)
{
case 1 : encryptedChar =
static_cast<char>
(((encryptedChar + 3) % NUM_LETTERS) +
ASCII_A);
break;
case 2 : encryptedChar =
static_cast<char>
(((encryptedChar + 17) % NUM_LETTERS) +
ASCII_A);
break;
case 3 : switch (encryptedChar)
{
case 'A' : encryptedChar = 'H'; break;
case 'B' : encryptedChar = 'U'; break;
case 'C' : encryptedChar = 'I'; break;
case 'D' : encryptedChar = 'P'; break;
case 'E' : encryptedChar = 'N'; break;
case 'F' : encryptedChar = 'W'; break;
case 'G' : encryptedChar = 'C'; break;
case 'H' : encryptedChar = 'K'; break;
case 'I' : encryptedChar = 'E'; break;
case 'J' : encryptedChar = 'X'; break;
case 'K' : encryptedChar = 'Q'; break;
case 'L' : encryptedChar = 'Z'; break;
case 'M' : encryptedChar = 'O'; break;
case 'N' : encryptedChar = 'V'; break;
case 'O' : encryptedChar = 'S'; break;
case 'P' : encryptedChar = 'B'; break;
case 'Q' : encryptedChar = 'L'; break;
case 'R' : encryptedChar = 'J'; break;
case 'S' : encryptedChar = 'D'; break;
case 'T' : encryptedChar = 'Y'; break;
case 'U' : encryptedChar = 'F'; break;
case 'V' : encryptedChar = 'R'; break;
case 'W' : encryptedChar = 'A'; break;
case 'X' : encryptedChar = 'G'; break;
case 'Y' : encryptedChar = 'T'; break;
case 'Z' : encryptedChar = 'M'; break;
}
} // end-switch
} // end-for
cout << encryptedChar << endl; // Now decrypted
}
else
cout << WORD_DELIMITER << endl;
}
} while (encryptedChar != END_OF_MESSAGE_CHAR);
// Sign-off
cout << "\nReached end of message...\n"
<< "Decryption completed.\n";
return 0;
}