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;

}