comparison enigma/machine.h @ 13:b9d124a15926

To improve cache performance, the enigma machine rotors are now stored together with the reflector in a vector.
author Brian Neal <bgneal@gmail.com>
date Mon, 02 Jul 2012 19:14:36 -0500
parents 424111a36ed7
children 919b7a0d1802
comparison
equal deleted inserted replaced
12:424111a36ed7 13:b9d124a15926
45 const std::string& plugboard_settings = ""); 45 const std::string& plugboard_settings = "");
46 46
47 // set the rotor display (starting position) - 3 rotor version 47 // set the rotor display (starting position) - 3 rotor version
48 void set_display(char left, char mid, char right) 48 void set_display(char left, char mid, char right)
49 { 49 {
50 assert(rotors.size() == 3); 50 assert(rotors.size() == 4);
51 51
52 rotors[0]->set_display(left); 52 rotors[1].set_display(left);
53 rotors[1]->set_display(mid); 53 rotors[2].set_display(mid);
54 rotors[2]->set_display(right); 54 rotors[3].set_display(right);
55 } 55 }
56 56
57 // set the rotor display (starting position) - 4 rotor version 57 // set the rotor display (starting position) - 4 rotor version
58 void set_display(char c0, char c1, char c2, char c3) 58 void set_display(char c0, char c1, char c2, char c3)
59 { 59 {
60 assert(rotors.size() == 4); 60 assert(rotors.size() == 5);
61 61
62 rotors[0]->set_display(c0); 62 rotors[1].set_display(c0);
63 rotors[1]->set_display(c1); 63 rotors[2].set_display(c1);
64 rotors[2]->set_display(c2); 64 rotors[3].set_display(c2);
65 rotors[3]->set_display(c3); 65 rotors[4].set_display(c3);
66 } 66 }
67 67
68 // Set the rotor display (starting position) using a string; the 68 // Set the rotor display (starting position) using a string; the
69 // string length must match the number of rotors in use or a 69 // string length must match the number of rotors in use or a
70 // enigma_machine_error exception will be thrown: 70 // enigma_machine_error exception will be thrown:
71 void set_display(const std::string& val) 71 void set_display(const std::string& val)
72 { 72 {
73 if (val.size() == 3 && rotors.size() == 3) 73 if (val.size() == 3 && rotors.size() == 4)
74 { 74 {
75 set_display(val[0], val[1], val[2]); 75 set_display(val[0], val[1], val[2]);
76 } 76 }
77 else if (val.size() == 4 && rotors.size() == 4) 77 else if (val.size() == 4 && rotors.size() == 5)
78 { 78 {
79 set_display(val[0], val[1], val[2], val[3]); 79 set_display(val[0], val[1], val[2], val[3]);
80 } 80 }
81 else 81 else
82 { 82 {
86 86
87 // return the rotor display (starting position) as a string 87 // return the rotor display (starting position) as a string
88 std::string get_display() const 88 std::string get_display() const
89 { 89 {
90 std::string result; 90 std::string result;
91 for (const auto& r : rotors) 91 for (std::size_t i = 1; i < rotors.size(); ++i)
92 { 92 {
93 result += r->get_display(); 93 result += rotors[i].get_display();
94 } 94 }
95 return result; 95 return result;
96 } 96 }
97 97
98 // simulate front panel key press; returns the lamp character that is lit 98 // simulate front panel key press; returns the lamp character that is lit
141 // 141 //
142 std::string army_str() const { return str(true); } 142 std::string army_str() const { return str(true); }
143 std::string navy_str() const { return str(false); } 143 std::string navy_str() const { return str(false); }
144 144
145 private: 145 private:
146 rotor_vector rotors; 146 // Note that to improve cache performance, the rotors and reflectors are stored
147 std::shared_ptr<rotor> reflector; 147 // in a contiguous vector.
148 std::vector<rotor> rotors; // rotor & reflector array
148 plugboard pb; 149 plugboard pb;
149 rotor* r_rotor; // rightmost rotor 150 rotor* r_rotor; // rightmost rotor
150 rotor* m_rotor; // 2nd to right rotor 151 rotor* m_rotor; // 2nd to right rotor
151 rotor* l_rotor; // 3rd to right rotor 152 rotor* l_rotor; // 3rd to right rotor
152 153
186 // perform an encrypt or decrypt operation 187 // perform an encrypt or decrypt operation
187 // signal_num - the wire (0-25) that the simulated current occurs on 188 // signal_num - the wire (0-25) that the simulated current occurs on
188 // Returns a lamp number to light (an integer 0-25). 189 // Returns a lamp number to light (an integer 0-25).
189 int electric_signal(int signal_num) 190 int electric_signal(int signal_num)
190 { 191 {
191 int pos = pb.signal(signal_num); 192 int n = pb.signal(signal_num);
192 193
193 for (auto r = rotors.rbegin(); r != rotors.rend(); ++r) 194 if (rotors.size() == 4) // 3 rotors + reflector
194 { 195 {
195 pos = (*r)->signal_in(pos); 196 n = rotors[3].signal_in(n);
196 } 197 n = rotors[2].signal_in(n);
197 198 n = rotors[1].signal_in(n);
198 pos = reflector->signal_in(pos); 199 n = rotors[0].signal_in(n); // reflector
199 200 n = rotors[1].signal_out(n);
200 for (const auto& r : rotors) 201 n = rotors[2].signal_out(n);
201 { 202 n = rotors[3].signal_out(n);
202 pos = r->signal_out(pos); 203 }
203 } 204 else // Kriegsmarine 4 rotor + reflector
204 205 {
205 return pb.signal(pos); 206 n = rotors[4].signal_in(n);
207 n = rotors[3].signal_in(n);
208 n = rotors[2].signal_in(n);
209 n = rotors[1].signal_in(n);
210 n = rotors[0].signal_in(n); // reflector
211 n = rotors[1].signal_out(n);
212 n = rotors[2].signal_out(n);
213 n = rotors[3].signal_out(n);
214 n = rotors[4].signal_out(n);
215 }
216 return pb.signal(n);
206 } 217 }
207 218
208 std::string str(bool army) const; 219 std::string str(bool army) const;
209 }; 220 };
210 } 221 }