-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmachine.cpp
More file actions
153 lines (124 loc) · 3.54 KB
/
machine.cpp
File metadata and controls
153 lines (124 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include"errors.h"
#include"machine.h"
// #include"components.h"
#include<iostream>
using namespace std;
EnigmaMachine::EnigmaMachine() {
};
int EnigmaMachine::setupComponent(ifstream& in_stream, string type, int rotor_num ) {
Component* new_comp = new Component(type, rotor_num);
int config_status = new_comp->Configure(in_stream);
if (config_status > 0) {
return config_status;
}
if (type == "plugboard") {
this->plugboard = new_comp;
} else if (type == "reflector") {
this->reflector = new_comp;
} else {
this->rotors[rotor_num] = new_comp;
}
return NO_ERROR;
}
void EnigmaMachine::setNumRotors(int num_rotors) {
this->num_rotors = num_rotors;
this->rotors = new Component* [num_rotors + 1] {};
}
int EnigmaMachine::configureStartingPositions(ifstream& in_stream) {
int positions[this->num_rotors]{};
int number;
int i = 0;
while(true) {
//Check to see if next block of characters (until next whitespace) are all numeric
char ch;
int cur_position = in_stream.tellg();
in_stream >> ws;
in_stream.get(ch);
if (in_stream.eof()) break;
while (!isspace(ch)) {
int numeric_status = checkNumeric(ch);
if (numeric_status > 0) {
return(numeric_status);
}
in_stream.get(ch);
}
in_stream.seekg(cur_position);
//extract number from file
in_stream >> number;
if (in_stream.eof()) break;
//check numbers between range of 0 - 25 (to index alphabet)
if (number < 0 || number > 25) {
return INVALID_INDEX;
}
if (i > num_rotors - 1 ) {
break;
}
positions[i] = number;
i++;
}
if (i < this->num_rotors) {
return NO_ROTOR_STARTING_POSITION;
}
setStartingPositions(positions);
return NO_ERROR;
}
int EnigmaMachine::checkNumeric(char ch) {
int test_int = ch;
if (test_int < 48 || test_int > 57) {
return NON_NUMERIC_CHARACTER;
} else {
return NO_ERROR;
}
}
void EnigmaMachine::setStartingPositions(int positions[]) {
for (int i = 0 ; i < this->num_rotors ; i++) {
this->rotors[i]->setPosition(positions[i]);
}
};
void EnigmaMachine::rotateSystem() {
//rotors rotated from last to first
//Component->rotate() returns true if next rotor needs to rotate too
//so loop 'continues', else 'breaks' - hence propogating rotation across system
for (int i = this->num_rotors - 1 ; i >= 0 ; i--) {
if (this->rotors[i]->rotate()) {
continue;
} else {
break;
}
}
}
int EnigmaMachine::EncryptDecrypt(const char letter) {
int num_equiv = letter;
if (num_equiv < 65 || num_equiv > 90) {
return INVALID_INPUT_CHARACTER;
}
//map ASCII letter to 0-25 representation
num_equiv -= 65;
char enc_character = reversibleEncryption(num_equiv);
cout << enc_character;
return NO_ERROR;
}
char EnigmaMachine::reversibleEncryption(int input) {
this->rotateSystem();
int encrypted = this->plugboard->convertReversible(input);
for (int i = num_rotors - 1 ; i >= 0 ; i-- ) {
encrypted = this->rotors[i]->convertForwards(encrypted);
}
encrypted = this->reflector->convertReversible(encrypted);
for (int i = 0 ; i < num_rotors ; i++ ) {
encrypted = this->rotors[i]->convertBackwards(encrypted);
}
encrypted = this->plugboard->convertReversible(encrypted);
//map back to ASCII representation for character
encrypted += 65;
char output = encrypted;
return output;
}
EnigmaMachine::~EnigmaMachine() {
for (int i = 0; i < this->num_rotors ; i++) {
delete this->rotors[i];
}
delete [] this->rotors;
delete this->plugboard;
delete this->reflector;
}