/* Programmer: Jennifer Leopold Date: October 8, 2015
File: hw6_functs.cpp
Purpose: Function definitions used for simulating the
processing of a message through a simplified
Enigma machine containing "interchangeable"
rotors.
*/
#include <iostream>
#include "hw6_functs.h"
using namespace std;
void outputGreeting()
{
cout << "Ready to decrypt message...\n\n";
return;
}
void outputSignOff()
{
cout << "\nReached end of message...\n"
<< "Decryption completed.\n";
return;
}
short getShortInput(const string prompt,
const short minVal, const short maxVal)
{
short input;
bool invalidInput;
do
{
cout << prompt;
cin >> input;
invalidInput = (input < minVal) || (input > maxVal);
if (invalidInput)
cout << "Invalid: input must be between "
<< minVal << " and " << maxVal
<< " (inclusive)!\n\n";
} while (invalidInput);
return(input);
}
char getCharInput()
{
char ch;
bool invalidInput;
do
{
cout << "\nEnter character ('A'..'Z', '_', or '.'): ";
cin >> ch;
invalidInput = ((ch < 'A') || (ch > 'Z')) &&
((ch != '.') && (ch != '_'));
if (invalidInput)
cout << "Invalid character entered!\n";
} while (invalidInput);
return(ch);
}
void getRotorSelections(short& leftRotor, short& middleRotor,
short& rightRotor)
{
bool invalidInput;
leftRotor = getShortInput("Enter leftmost rotor number: ",
1, NUM_ROTORS);
do
{
middleRotor = getShortInput("Enter middle rotor number: ",
1, NUM_ROTORS);
invalidInput = (middleRotor == leftRotor);
if (invalidInput)
cout << "Rotor " << middleRotor
<< " already in use, make a different selection!\n";
} while (invalidInput);
do
{
rightRotor = getShortInput("Enter rightmost rotor number: ",
1, NUM_ROTORS);
invalidInput = (rightRotor == leftRotor) ||
(rightRotor == middleRotor);
if (invalidInput)
cout << "Rotor " << rightRotor
<< " already in use, make a different selection!\n";
} while (invalidInput);
return;
}
char rotor1(const char ch)
{
char encryptedChar;
static char prevChar = ASCII_A;
short asciiValue = static_cast<short>(shiftChar(prevChar,ch));
encryptedChar = static_cast<char>
(((asciiValue + 3) % NUM_LETTERS) +
ASCII_A);
prevChar = ch;
return(encryptedChar);
}
char rotor2(const char ch)
{
char encryptedChar;
static char prevChar = ASCII_A;
short asciiValue = static_cast<short>(shiftChar(prevChar,ch));
encryptedChar = static_cast<char>
(((asciiValue + 17) % NUM_LETTERS) +
ASCII_A);
prevChar = ch;
return(encryptedChar);
}
char rotor3(const char ch)
{
char encryptedChar;
static char prevChar = ASCII_A;
switch (shiftChar(prevChar,ch))
{
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;
}
prevChar = ch;
return(encryptedChar);
}
char rotor4(const char ch)
{
static char prevChar = ASCII_A;
short asciiValue = static_cast<short>(shiftChar(prevChar,ch));
if (asciiValue % 2)
asciiValue++;
else
asciiValue--;
prevChar = ch;
return(static_cast<char>(asciiValue));
}
char rotor5(const char ch)
{
static char prevChar = ASCII_A;
short asciiValue = static_cast<short>(shiftChar(prevChar,ch));
if (asciiValue == 'A')
asciiValue = 'A';
else if (asciiValue == 'Z')
asciiValue = 'B';
else if (asciiValue % 3 == 0)
asciiValue += 3;
else if (asciiValue % 3 == 1)
asciiValue++;
else if (asciiValue % 3 == 2)
asciiValue--;
prevChar = ch;
return(static_cast<char>(asciiValue));
}
char translateChar(const short whichRotor,
const char encryptedChar)
{
char decryptedChar;
switch (whichRotor)
{
case 1 : decryptedChar = rotor1(encryptedChar);
break;
case 2 : decryptedChar = rotor2(encryptedChar);
break;
case 3 : decryptedChar = rotor3(encryptedChar);
break;
case 4 : decryptedChar = rotor4(encryptedChar);
break;
case 5 : decryptedChar = rotor5(encryptedChar);
break;
default: cout << "Invalid rotor in function "
<< "translateChar!\n";
exit(1);
}
return(decryptedChar);
}
bool isMultipleOf3(const short val)
{
return(val % 3 == 0);
}
char shiftChar(const char prevChar, const char newChar)
{
return(((newChar-ASCII_A)+(prevChar-ASCII_A))% NUM_LETTERS +
ASCII_A);
}