Mercurial > public > cpp-enigma
comparison enigma/rotor.h @ 0:74ebb2150658
Initial commit. Working on the rotor class.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 21 Jun 2012 21:05:26 -0500 |
parents | |
children | 1459e74fda3f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:74ebb2150658 |
---|---|
1 #ifndef CPP_ENIGMA_ROTOR_H | |
2 #define CPP_ENIGMA_ROTOR_H | |
3 // Copyright (C) 2012 by Brian Neal. | |
4 // This file is part of Cpp-Enigma, the Enigma Machine simulation. | |
5 // Cpp-Enigma is released under the MIT License (see License.txt). | |
6 // | |
7 // rotor.h - This file contains the rotor class. | |
8 | |
9 #include <string> | |
10 #include "enigma_types.h" | |
11 | |
12 | |
13 namespace enigma | |
14 { | |
15 class rotor_error : public enigma_error | |
16 { | |
17 public: | |
18 explicit rotor_error(const std::string& what_arg) | |
19 : enigma_error(what_arg) | |
20 {} | |
21 }; | |
22 | |
23 // The rotor class represents the Enigma Machine rotors (Walzen). | |
24 // | |
25 // A rotor has 26 circularly arranged pins on the right (entry) side and 26 | |
26 // contacts on the left side. Each pin is connected to a single contact by | |
27 // internal wiring, thus establishing a substitution cipher. We represent this | |
28 // wiring by establishing a mapping from a pin to a contact (and vice versa for | |
29 // the return path). Internally we number the pins and contacts from 0-25 in a | |
30 // clockwise manner with 0 being the "top". | |
31 // | |
32 // An alphabetic or numeric ring is fastened to the rotor by the operator. The | |
33 // labels of this ring are displayed to the operator through a small window on | |
34 // the top panel. The ring can be fixed to the rotor in one of 26 different | |
35 // positions; this is called the ring setting (Ringstellung). We will number | |
36 // the ring settings from 0-25 where 0 means no offset (e.g. the letter "A" is | |
37 // mapped to pin 0 on an alphabetic ring). A ring setting of 1 means the letter | |
38 // "B" is mapped to pin 0. | |
39 // | |
40 // Each rotor can be in one of 26 positions on the spindle, with position 0 | |
41 // where pin/contact 0 is being indicated in the operator window. The rotor | |
42 // rotates towards the operator by mechanical means during normal operation as | |
43 // keys are being pressed during data entry. Position 1 is thus defined to be | |
44 // one step from position 0. Likewise, position 25 is the last position before | |
45 // another step returns it to position 0, completing 1 trip around the spindle. | |
46 // | |
47 // Finally, a rotor has a "stepping" or "turnover" parameter. Physically this | |
48 // is implemented by putting a notch on the alphabet ring and it controls when | |
49 // the rotor will "kick" the rotor to its left, causing the neighbor rotor to | |
50 // rotate. Most rotors had one notch, but some Kriegsmarine rotors had 2 | |
51 // notches and thus rotated twice as fast. | |
52 // | |
53 // Note that due to the system of ratchets and pawls, the middle rotor (in a 3 | |
54 // rotor Enigma) can "double-step". The middle rotor will advance on the next | |
55 // step of the first rotor a second time in a row, if the middle rotor is in | |
56 // its own turnover position. | |
57 // | |
58 // Note that we allow the stepping parameter to be None. This indicates the | |
59 // rotor does not rotate. This allows us to model the entry wheel and | |
60 // reflectors as stationary rotors. | |
61 | |
62 class rotor | |
63 { | |
64 public: | |
65 // rotor constructor: | |
66 // | |
67 // model_name - e.g. "I", "II", "III", "Beta", "Gamma" | |
68 // | |
69 // wiring - this should be a string of 26 alphabetic characters that | |
70 // represents the internal wiring transformation of the signal as it enters | |
71 // from the right side. This is the format used in various online | |
72 // resources. For example, for the Wehrmacht Enigma type I rotor the | |
73 // mapping is "EKMFLGDQVZNTOWYHXUSPAIBRCJ". | |
74 // | |
75 // ring_setting - this should be an integer from 0-25, inclusive, which | |
76 // indicates the Ringstellung. A value of 0 means there is no offset; e.g. | |
77 // the letter "A" is fixed to pin 0. A value of 1 means "B" is mapped to | |
78 // pin 0. | |
79 // | |
80 // stepping - this is the stepping or turnover parameter. It should be | |
81 // a string such as "Q". This will indicate that when the rotor transitions | |
82 // from "Q" to "R" (by observing the operator window), the rotor will "kick" | |
83 // the rotor to its left, causing it to rotate. If the rotor has more than one | |
84 // notch, a string of length 2 could be used, e.g. "ZM". Another way to think | |
85 // of this parameter is that when a character in the stepping string is visible | |
86 // in the operator window, a notch is lined up with the pawl on the left side | |
87 // of the rotor. This will allow the pawl to push up on the rotor *and* the | |
88 // rotor to the left when the next key is depressed. | |
89 // | |
90 // Note that for purposes of simulation, our rotors will always use | |
91 // alphabetic labels A-Z. In reality, the Heer & Luftwaffe devices used | |
92 // numbers 01-26, and Kriegsmarine devices used A-Z. Our usage of A-Z is | |
93 // simply for simulation convenience. | |
94 // display. | |
95 | |
96 rotor(const char* name, const char* wiring, int ring_setting = 0, const char* stepping = 0); | |
97 | |
98 // Returns the rotor name: | |
99 const std::string& name() const { return rotor_name; } | |
100 | |
101 // Spin the rotor such that the string val appears in the operator window: | |
102 void set_display(const char* val); | |
103 | |
104 // Returns what is currently being displayed in the operator window: | |
105 std::string get_display() const; | |
106 | |
107 // Simulate a signal entering the rotor from the right at a given pin: | |
108 // n must be an integer between 0 and 25. | |
109 // Returns the contact number of the output signal (0-25). | |
110 int signal_in(int n) const; | |
111 | |
112 // Simulate a signal entering the rotor from the left at a given contact position n. | |
113 // n must be an integer between 0 and 25. | |
114 // Returns the pin number of the output signal (0-25). | |
115 int signal_out(int n) const; | |
116 | |
117 // Return true if this rotor has a notch in the stepping position and false otherwise: | |
118 bool notch_over_pawl() const; | |
119 | |
120 // Rotate the rotor forward one step: | |
121 void rotate(); | |
122 | |
123 private: | |
124 std::string rotor_name; | |
125 std::string wiring_str; | |
126 int ring_setting; | |
127 int pos; | |
128 int rotations; | |
129 }; | |
130 } | |
131 | |
132 #endif |