@ondoher/enigma 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +636 -0
- package/enigma-logo.jpg +0 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
<div style="text-align: right">
|
|
2
|
+
<div><img src="./enigma-logo.jpg" height="75"/></div>
|
|
3
|
+
<h1>Toolkit</h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
# Getting Started
|
|
7
|
+
|
|
8
|
+
The Enigma toolkit is released as a nodejs ESM module. ESM is a relatively new
|
|
9
|
+
standard for importing modules, and can present challenges to developers who
|
|
10
|
+
need to mix the two. Using CJS modules in an ESM project is pretty straight
|
|
11
|
+
forward, but the opposite is not true. Here is a good page that covers this
|
|
12
|
+
issue [Mixing ESM and CJS](https://adamcoster.com/blog/commonjs-and-esm-importexport-compatibility-examples).
|
|
13
|
+
To work with this code, your best bet is to create your own project also as ESM,
|
|
14
|
+
by either renaming your files with the extension mjs, or adding
|
|
15
|
+
```"type": "module"``` to your package.js file.
|
|
16
|
+
|
|
17
|
+
To install the module, use the command:
|
|
18
|
+
|
|
19
|
+
```npm install @ondoher/enigma```
|
|
20
|
+
|
|
21
|
+
You can then import this into your code like this:
|
|
22
|
+
|
|
23
|
+
```JavaScript
|
|
24
|
+
import {Enigma} from '@ondoher/enigma';
|
|
25
|
+
|
|
26
|
+
var enigma = new Enigma({reflector: 'B'});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The API is broken into two main parts, the simulator and the message generator.
|
|
30
|
+
With the simulator you can construct an entire Enigma, or just create instances
|
|
31
|
+
of the individual components. This API is provided as a working reference that
|
|
32
|
+
can be used to validate the simulator being built. You can match the input and
|
|
33
|
+
output of your simulation against the reference implementation to locate
|
|
34
|
+
failures to be corrected. The API also provides a way to hook into the various
|
|
35
|
+
stages of encoding to observe the transformation of state and data as it occurs.
|
|
36
|
+
|
|
37
|
+
# Simulation
|
|
38
|
+
|
|
39
|
+
## Events
|
|
40
|
+
Each class below, except Inventory, has a method named `listen`. Call this
|
|
41
|
+
method to pass a function that will be called when significant events happen to
|
|
42
|
+
the class instance. When creating an instance of the Enigma, this callback
|
|
43
|
+
will be passed to every constructed component.
|
|
44
|
+
|
|
45
|
+
The signature of this callback should look like this:
|
|
46
|
+
|
|
47
|
+
`function (event, name, message, info)`
|
|
48
|
+
|
|
49
|
+
### **Parameters**
|
|
50
|
+
- **event** a string that identifies the specific action being taken.
|
|
51
|
+
- **name** the name of the class instance that has fired this event
|
|
52
|
+
- **message** a string that describes the event taking place
|
|
53
|
+
- **info** an object that contains information relevant to the event
|
|
54
|
+
|
|
55
|
+
The specific events and data are defined in the class documentation that
|
|
56
|
+
follows.
|
|
57
|
+
|
|
58
|
+
## PlugBoard
|
|
59
|
+
Create an instance of this class to simulate the plug board component of an
|
|
60
|
+
Enigma.
|
|
61
|
+
|
|
62
|
+
### **Methods**
|
|
63
|
+
|
|
64
|
+
`constructor(name, settings)`
|
|
65
|
+
|
|
66
|
+
This is the constructor for the plugboard class. It takes these parameters:
|
|
67
|
+
|
|
68
|
+
#### **Parameters**
|
|
69
|
+
- **name** each encoder component in the system has a name. There is only one
|
|
70
|
+
plug board in the Enigma, so the name here doesn't really matter
|
|
71
|
+
- **settings**
|
|
72
|
+
- _alphabet_ (optional) set this to a string of letters that are an
|
|
73
|
+
alternative to the standard A-Z. Defaults to A-Z
|
|
74
|
+
- _map_ (optional) set this to a string that will set the mapping between
|
|
75
|
+
the position in the string to the output connector. Defaults to A-Z
|
|
76
|
+
|
|
77
|
+
`configure(settings)`
|
|
78
|
+
|
|
79
|
+
Call this method to configure the plug board. This must be called even if there
|
|
80
|
+
are no plug connections.
|
|
81
|
+
|
|
82
|
+
#### **Parameters**
|
|
83
|
+
- **settings** these are the settings to configure the plug board.
|
|
84
|
+
- _plugs_ (optional) either an array of strings or a single string. If it
|
|
85
|
+
is a string, it must be a space separated list of letter pairs that
|
|
86
|
+
connects one input letter to another. If it is an array then then each item
|
|
87
|
+
is a pair of letters to specify how the plugs are connected
|
|
88
|
+
|
|
89
|
+
`encode(direction, input)`
|
|
90
|
+
|
|
91
|
+
Call this method to encode a value in the given direction, right vs left.
|
|
92
|
+
|
|
93
|
+
#### **Parameters**
|
|
94
|
+
- **direction** `right` when moving towards the reflector `left` when moving
|
|
95
|
+
back
|
|
96
|
+
- **input** this is the input connector.
|
|
97
|
+
|
|
98
|
+
#### **Returns**
|
|
99
|
+
the output connector
|
|
100
|
+
|
|
101
|
+
#### **Events**
|
|
102
|
+
|
|
103
|
+
`encode-right, encode-left`
|
|
104
|
+
|
|
105
|
+
These events will be fired during encoding. The info parameter will have these
|
|
106
|
+
fields.
|
|
107
|
+
|
|
108
|
+
- **input** the number of the connector that received input
|
|
109
|
+
- **output** the number of the connector for the encoded value
|
|
110
|
+
|
|
111
|
+
## Rotor
|
|
112
|
+
|
|
113
|
+
Create an instance of this class to construct a Rotor object. The Rotor class
|
|
114
|
+
encapsulates many of the peculiar behaviors of the Enigma. All connector values
|
|
115
|
+
here are specified in physical space. See the [documentation](./docs/enigma.md)
|
|
116
|
+
for an explanation.
|
|
117
|
+
|
|
118
|
+
### **Methods**
|
|
119
|
+
|
|
120
|
+
`constructor(name, settings)`
|
|
121
|
+
|
|
122
|
+
#### **Parameters**
|
|
123
|
+
- **name** the name of the rotor; under normal circumstances this will be the
|
|
124
|
+
string 'rotor-' plus the standard name for the rotor, for example 'rotor-IV'
|
|
125
|
+
- **settings** an object that contains the various options that define the
|
|
126
|
+
the rotor and how it is configured.
|
|
127
|
+
- _alphabet_ (optional) set this to a string of letters that are an
|
|
128
|
+
alternative to the standard A-Z. Defaults to A-Z
|
|
129
|
+
- _map_ a string that defines the mapping between the input and output
|
|
130
|
+
connectors. The index into the string is the input connector and the value
|
|
131
|
+
of this string at that index is the output connector. For example
|
|
132
|
+
'EKMFLGDQVZNTOWYHXUSPAIBRCJ', which is the map for standard rotor I
|
|
133
|
+
- _ringSetting_ a number that specifies how far forward to offset the
|
|
134
|
+
outer ring relative to the internal wiring.
|
|
135
|
+
- _turnovers_ a string that specifies the relative location of where on the
|
|
136
|
+
rotor turnover will occur. The value here is the rotation value would be
|
|
137
|
+
displayed in the window when turnover happens, expressed as a character.
|
|
138
|
+
The standard rotors VI-VIII, available in the later model M3 had two
|
|
139
|
+
turnover locations, M and Z. Pass an empty string when the rotor does not
|
|
140
|
+
rotate during stepping
|
|
141
|
+
|
|
142
|
+
`setStartPosition(connector)`
|
|
143
|
+
|
|
144
|
+
Call this method to set the starting rotation for encoding.
|
|
145
|
+
|
|
146
|
+
#### **Parameters**
|
|
147
|
+
- **connector** This is a letter value that corresponds to what would appear in
|
|
148
|
+
the rotation window. This value will be adjusted for the ring setting.
|
|
149
|
+
|
|
150
|
+
`encode(direction, input)`
|
|
151
|
+
|
|
152
|
+
Call this method to map an input connector to an output connector when the
|
|
153
|
+
signal is moving in the given direction. The input connector represents a
|
|
154
|
+
physical location in real space. To get the logical connector for the rotor's
|
|
155
|
+
zero point we need to adjust the connector number for the current rotation.
|
|
156
|
+
|
|
157
|
+
#### **Parameters**
|
|
158
|
+
- **direction** `right` when moving towards the reflector `left` when moving
|
|
159
|
+
back
|
|
160
|
+
- **input** the input connector given in physical space.
|
|
161
|
+
|
|
162
|
+
#### **Returns**
|
|
163
|
+
the output connector in physical space
|
|
164
|
+
|
|
165
|
+
`step()`
|
|
166
|
+
|
|
167
|
+
Call this method to step the rotor
|
|
168
|
+
|
|
169
|
+
#### **Returns**
|
|
170
|
+
true if the next rotor should be stepped
|
|
171
|
+
|
|
172
|
+
`willTurnover()`
|
|
173
|
+
Call this method to see if the next step on this rotor will lead to turn over.
|
|
174
|
+
The Enigma class will call this on the middle rotor to handle double stepping.
|
|
175
|
+
|
|
176
|
+
#### **Returns**
|
|
177
|
+
true if the next step will cause turnover
|
|
178
|
+
|
|
179
|
+
`isfixed()`
|
|
180
|
+
|
|
181
|
+
Call this method to find whether this is a fixed rotor.
|
|
182
|
+
|
|
183
|
+
#### **Returns**
|
|
184
|
+
True if this is a fixed rotor.
|
|
185
|
+
|
|
186
|
+
### **Events**
|
|
187
|
+
|
|
188
|
+
`encode-right, encode-left`
|
|
189
|
+
|
|
190
|
+
These events will be fired during encoding. The info object will contain these
|
|
191
|
+
members
|
|
192
|
+
|
|
193
|
+
- **input** the physical input connector
|
|
194
|
+
- **output** the physical output connector
|
|
195
|
+
- **logicalInput** the logical connector that receives input. This value is
|
|
196
|
+
always relative to the internal wiring.
|
|
197
|
+
- **logicalOutput** the logical connector that gets the output.
|
|
198
|
+
- **rotation** current rotation offset
|
|
199
|
+
|
|
200
|
+
`step`
|
|
201
|
+
|
|
202
|
+
This event will be fired every time a rotor is stepped. The info object will
|
|
203
|
+
contain these members
|
|
204
|
+
|
|
205
|
+
#### **Parameters**
|
|
206
|
+
- **rotation** the current rotation offset
|
|
207
|
+
- **ringSetting** the configured ringSetting for this rotor.
|
|
208
|
+
- **turnover** true if the next rotor should be stepped
|
|
209
|
+
|
|
210
|
+
## Reflector
|
|
211
|
+
Create an instance of this class to construct a reflector class. Unlike most
|
|
212
|
+
other encoders, the reflector only has a single set of connectors. Input and
|
|
213
|
+
output happen on the same connectors, with pairs of them linked. Because of
|
|
214
|
+
this, reflectors only encode in a single direction.
|
|
215
|
+
|
|
216
|
+
### **Methods**
|
|
217
|
+
|
|
218
|
+
`constructor(name, settings)`
|
|
219
|
+
|
|
220
|
+
#### **Parameters**
|
|
221
|
+
- **name** the name of the reflector, under normal circumstances this be the
|
|
222
|
+
string 'reflector-' plus the standard name for the reflector, for example
|
|
223
|
+
'reflector-C'
|
|
224
|
+
- **settings** an object that contains the various options that define the
|
|
225
|
+
the reflector and how it is setup.
|
|
226
|
+
- _alphabet_ (optional) set this to a string of letters that are an
|
|
227
|
+
alternative to the standard A-Z. Defaults to A-Z
|
|
228
|
+
- _map_ a string that defines the mapping between the input and output
|
|
229
|
+
connectors. The index into the string is the input connector and the value
|
|
230
|
+
of this string at that index is the output connector. For example,
|
|
231
|
+
'YRUHQSLDPXNGOKMIEBFZCWVJAT' which is the map for standard reflector B.
|
|
232
|
+
|
|
233
|
+
`encode(direction, input)`
|
|
234
|
+
|
|
235
|
+
Call this method to encode a value when reversing the encoding direction of the
|
|
236
|
+
Enigma. As the point where direction changes this does not have a distinction
|
|
237
|
+
between a left and right signal path.
|
|
238
|
+
|
|
239
|
+
#### **Parameters**
|
|
240
|
+
- **direction** since this the point where signal direction changes from right
|
|
241
|
+
to left this parameter is not used.
|
|
242
|
+
- **input** this is the input connector
|
|
243
|
+
|
|
244
|
+
#### **Returns**
|
|
245
|
+
the output connector
|
|
246
|
+
|
|
247
|
+
### **Events**
|
|
248
|
+
|
|
249
|
+
`encode`
|
|
250
|
+
|
|
251
|
+
This event will be fired during encoding. The info parameter will have these
|
|
252
|
+
fields.
|
|
253
|
+
|
|
254
|
+
- **input** the number of the connector that received input
|
|
255
|
+
- **output** the number of the connector for the encoded value
|
|
256
|
+
|
|
257
|
+
## Enigma
|
|
258
|
+
|
|
259
|
+
Create an instance of this class to construct a full Enigma.
|
|
260
|
+
|
|
261
|
+
### **Methods**
|
|
262
|
+
|
|
263
|
+
`constructor(settings)`
|
|
264
|
+
|
|
265
|
+
The constructor for the Enigma.
|
|
266
|
+
|
|
267
|
+
#### **Parameters**
|
|
268
|
+
- **settings** The settings here are for the unconfigurable options of the
|
|
269
|
+
device.
|
|
270
|
+
- _alphabet_ (optional) set this to a string of letters that are an
|
|
271
|
+
alternative to the standard A-Z. Defaults to A-Z
|
|
272
|
+
- _entryDisk_ (optional) the name of entry disc in the inventory this
|
|
273
|
+
defaults to 'default'
|
|
274
|
+
- _reflector_ for the Enigma I or M3 this specifies one of three possible
|
|
275
|
+
standard reflectors from the inventory which are A, B, and C. For the M4,
|
|
276
|
+
Thin-B and Thin-C have been defined.
|
|
277
|
+
|
|
278
|
+
`configure(settings)`
|
|
279
|
+
|
|
280
|
+
Call this method to configure the enigma instance for daily setup.
|
|
281
|
+
|
|
282
|
+
#### **Parameters**
|
|
283
|
+
- **settings** the configuration parameters for the device.
|
|
284
|
+
- _plugs_ (optional) this specifies how the plug board should be configured.
|
|
285
|
+
This is either a string with the plugs specified as pairs of letters
|
|
286
|
+
separated by a single space, or an array of letter pairs.
|
|
287
|
+
- _rotors_ this is an array of strings that specifies which rotors should be
|
|
288
|
+
installed on the device and in which order. These rotors have been
|
|
289
|
+
predefined: I-V for the model I, VI-VIII are added for the Model M3, and
|
|
290
|
+
Beta and Gamma are the fixed rotors for the M4. The order here is
|
|
291
|
+
significant and is given in the left to right direction. This means that
|
|
292
|
+
last name in this list is the first rotor used in the forward direction and
|
|
293
|
+
last used in the backward direction. Each element is the name of the rotor
|
|
294
|
+
to use in the corresponding position. Stepping stops at the first fixed
|
|
295
|
+
rotor.
|
|
296
|
+
- _ringSettings_ (optional) This is either a string, or an array of
|
|
297
|
+
numbers. The index of each letter in the alphabet, or the number in the
|
|
298
|
+
array, is the ring setting for a rotor. Like the rotors, these are given
|
|
299
|
+
from left to right.
|
|
300
|
+
|
|
301
|
+
`step()`
|
|
302
|
+
|
|
303
|
+
Call this method to step the Enigma. This will rotate the first rotor to the
|
|
304
|
+
right and step and double step when necessary.
|
|
305
|
+
|
|
306
|
+
`setStart(start)`
|
|
307
|
+
|
|
308
|
+
#### **Parameters**
|
|
309
|
+
- **start** this is either a string of an array of numbers. The length of the
|
|
310
|
+
string or the array should match the number of rotors and are given left to
|
|
311
|
+
right. If start is a string then the letters of the string specify the start
|
|
312
|
+
value seen in the window for the corresponding rotor. If it is an array then
|
|
313
|
+
each number will be the one-based rotation value.
|
|
314
|
+
|
|
315
|
+
`keyPress(letter)`
|
|
316
|
+
|
|
317
|
+
Call this method to encode a single letter. This will step the Enigma before
|
|
318
|
+
encoding the letter.
|
|
319
|
+
|
|
320
|
+
#### **Parameters**
|
|
321
|
+
- **letter** this method will force the letter parameter to uppercase. If it is
|
|
322
|
+
anything except a member of the given alphabet it will return undefined. For
|
|
323
|
+
any other character except a space it will also output a warning to the
|
|
324
|
+
console.
|
|
325
|
+
|
|
326
|
+
#### **Returns**
|
|
327
|
+
undefined or the encoded character.
|
|
328
|
+
|
|
329
|
+
`encode(start, text)`
|
|
330
|
+
|
|
331
|
+
Call this method to encode a whole string.
|
|
332
|
+
|
|
333
|
+
#### **Parameters**
|
|
334
|
+
- **start** the start positions for the rotors. This parameter is the same as
|
|
335
|
+
what's passed to `setStart`.
|
|
336
|
+
- **text** This is the string to be encoded. Any characters in this string that
|
|
337
|
+
are not part of the defined alphabet are ignored.
|
|
338
|
+
|
|
339
|
+
#### **Returns**
|
|
340
|
+
the encoded string. Passing the result of this method back through the encode
|
|
341
|
+
method should produce the original text.
|
|
342
|
+
|
|
343
|
+
### **Events**
|
|
344
|
+
|
|
345
|
+
In addition to firing all the events from its components, the Enigma will also
|
|
346
|
+
fire these events.
|
|
347
|
+
|
|
348
|
+
`input`
|
|
349
|
+
|
|
350
|
+
This is fired at the beginning of encoding each letter. It is fired after
|
|
351
|
+
verifying the letter, but before stepping. The info parameter contains these
|
|
352
|
+
fields.
|
|
353
|
+
|
|
354
|
+
- **letter** the letter to be encoded
|
|
355
|
+
|
|
356
|
+
`output`
|
|
357
|
+
|
|
358
|
+
This is fired after encoding each letter. The info parameter contains these
|
|
359
|
+
fields.
|
|
360
|
+
|
|
361
|
+
- **letter** the encoded letter.
|
|
362
|
+
|
|
363
|
+
### **Example**
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
import {Enigma} from '@ondoher/enigma';
|
|
367
|
+
|
|
368
|
+
var enigma = new Enigma({reflector: 'B'});
|
|
369
|
+
|
|
370
|
+
enigma.configure({
|
|
371
|
+
rotors: ['III', 'VI', 'VIII'],
|
|
372
|
+
ringSetting: [1, 8, 13],
|
|
373
|
+
plugs: 'AN EZ HK IJ LR MQ OT PV SW UX'
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
var message = 'YKAENZAPMSCHZBFOCUVMRMDPYCOFHADZIZMEFXTHFLOLPZLFGGBOTGOXGRETDWTJIQHLMXVJWKZUASTR'
|
|
377
|
+
var decoded = enigma.encode('UZV', message)
|
|
378
|
+
|
|
379
|
+
console.log(decoded)
|
|
380
|
+
|
|
381
|
+
//STEUEREJTANAFJORDJANSTANDORTQUAAACCCVIERNEUNNEUNZWOFAHRTZWONULSMXXSCHARNHORSTHCO
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Inventory
|
|
385
|
+
|
|
386
|
+
The inventory class is used to save named definitions of different components
|
|
387
|
+
that can be used by the Enigma. The module doesn't export the class, but instead
|
|
388
|
+
exports an instance of it named `inventory`. Components that have been added to
|
|
389
|
+
this inventory can be passed to the Enigma for configuration. By default the
|
|
390
|
+
following components are already defined:
|
|
391
|
+
|
|
392
|
+
- **Rotors** I, II, III, IV, V, VI, VII, VI, Beta, and Gamma. VI, VII, and VIII
|
|
393
|
+
are used in the M3 and M4 and have two turnover points. The last two are
|
|
394
|
+
fixed rotors used in the M4.
|
|
395
|
+
- **Reflectors** A, B, C, Thin-B, and Thin-C. Those last two are the thin
|
|
396
|
+
reflectors used in the M4.
|
|
397
|
+
- **EntryDisc** the system only defines one entry disk, named default. It's just
|
|
398
|
+
a simple pass through.
|
|
399
|
+
|
|
400
|
+
### **Methods**
|
|
401
|
+
|
|
402
|
+
`addRotor(name, map, turnovers)`
|
|
403
|
+
|
|
404
|
+
Call this method to add a new rotor definition.
|
|
405
|
+
|
|
406
|
+
#### **Parameters**
|
|
407
|
+
- **name** the name of the rotor being added. This name will be used when
|
|
408
|
+
specifying the rotors to use for the Enigma configuration.
|
|
409
|
+
- **map** a string specifying the connector mapping. The index of the string is
|
|
410
|
+
the logical coordinate of the connector, the character at that index is the
|
|
411
|
+
output connector. To be exact, it would be the position of that character in
|
|
412
|
+
the given alphabet. So, in the map 'EKMFLGDQVZNTOWYHXUSPAIBRCJ', input
|
|
413
|
+
connector 0 would map to output connector 4 and input connector 1 would map
|
|
414
|
+
to output connector 10. Remember that the connectors are numbered starting
|
|
415
|
+
at 0.
|
|
416
|
+
- **turnovers** this is a string of characters representing the turnover
|
|
417
|
+
location on the disk. This letter would be the value shown in the window to
|
|
418
|
+
the operator. In Rotor I this is 'Q' in rotors VI, VII, and VIII there are
|
|
419
|
+
two turnover locations, 'M' and 'Z'. Pass an empty string if this is a fixed
|
|
420
|
+
rotor
|
|
421
|
+
|
|
422
|
+
`addReflector(name, map)`
|
|
423
|
+
|
|
424
|
+
Call this method to add a new reflector definition.
|
|
425
|
+
|
|
426
|
+
#### **Parameters**
|
|
427
|
+
- **name** this is the name that will be used to reference this reflector when
|
|
428
|
+
constructing an Enigma class.
|
|
429
|
+
- **map** this uses the same format used in the `addRotor` method
|
|
430
|
+
|
|
431
|
+
`addEntryDisc(name, map)`
|
|
432
|
+
|
|
433
|
+
Call this method to add a new entry disc. There was only one used in the
|
|
434
|
+
standard military models, but there were other versions that defined it
|
|
435
|
+
differently.
|
|
436
|
+
|
|
437
|
+
#### **Parameters**
|
|
438
|
+
- **name** this is the name that will be used to reference this entry disc when
|
|
439
|
+
constructing an Enigma class.
|
|
440
|
+
- **map** this uses the same format used in the `addRotor` method
|
|
441
|
+
|
|
442
|
+
`getRotor(name)`
|
|
443
|
+
|
|
444
|
+
Call this method to get the setup for a defined rotor.
|
|
445
|
+
|
|
446
|
+
#### **Parameters**
|
|
447
|
+
- **name** the name of the rotor as it was added to the inventory.
|
|
448
|
+
|
|
449
|
+
#### **Returns**
|
|
450
|
+
an object with these fields
|
|
451
|
+
- **map** the connection map for the rotor
|
|
452
|
+
- **turnovers** the locations where turnovers happen
|
|
453
|
+
|
|
454
|
+
`getReflector(name)`
|
|
455
|
+
|
|
456
|
+
Call this method to get the setup for a defined reflector.
|
|
457
|
+
|
|
458
|
+
#### **Parameters**
|
|
459
|
+
- **name** the name of the reflector as it was added to the inventory.
|
|
460
|
+
|
|
461
|
+
#### **Returns**
|
|
462
|
+
an object with these fields
|
|
463
|
+
- **map** the connection map for the reflector
|
|
464
|
+
|
|
465
|
+
`getEntryDisc(name)`
|
|
466
|
+
|
|
467
|
+
Call this method to get the setup for a defined entry disc.
|
|
468
|
+
|
|
469
|
+
#### **Parameters**
|
|
470
|
+
- **name** the name of the entry disk as it was added to the inventory.
|
|
471
|
+
|
|
472
|
+
#### **Returns**
|
|
473
|
+
an object with these fields
|
|
474
|
+
- **map** the connection map for the entry disc
|
|
475
|
+
|
|
476
|
+
# Message Generator
|
|
477
|
+
|
|
478
|
+
The message generator API consists of a single class `Generator` which is used
|
|
479
|
+
to generate random test data.
|
|
480
|
+
|
|
481
|
+
## Generator
|
|
482
|
+
|
|
483
|
+
### **Methods**
|
|
484
|
+
|
|
485
|
+
`generateEncodedText(settings)`
|
|
486
|
+
|
|
487
|
+
Call this method to generate some random text encoded with a random Enigma
|
|
488
|
+
configuration. The random text will be a few sentences from Hamlet.
|
|
489
|
+
|
|
490
|
+
#### **Parameters**
|
|
491
|
+
- **settings** (optional), alternative configuration settings for the Enigma
|
|
492
|
+
- _rotors_ (optional) alternate list of rotors to choose from. Defaults to
|
|
493
|
+
all defined rotors
|
|
494
|
+
- _fixed_ (optional) an array of fixed rotors to choose from. Defaults to
|
|
495
|
+
an empty list
|
|
496
|
+
- _reflectors_ (optional) an array of reflectors to choose from. Defaults to
|
|
497
|
+
A, B and C
|
|
498
|
+
|
|
499
|
+
#### **Returns**
|
|
500
|
+
the generated text and meta data. This is an object with these fields
|
|
501
|
+
|
|
502
|
+
- **setup** how the Enigma was configured
|
|
503
|
+
- _rotors_ an array of three rotor names, four if a fixed list was given
|
|
504
|
+
in the settings
|
|
505
|
+
- _ringSettings_ an array of offsets for the ring settings
|
|
506
|
+
- _plugs_ 10 pairs of letters that will be used as connections on the plug
|
|
507
|
+
board
|
|
508
|
+
- _reflector_ which reflector was configured
|
|
509
|
+
|
|
510
|
+
- **start** three letter or four string with the starting rotor offsets used to
|
|
511
|
+
encode the text.
|
|
512
|
+
- **message** the encoded text
|
|
513
|
+
- **clear** the unencoded text. This is provided to validate the simulation
|
|
514
|
+
result
|
|
515
|
+
|
|
516
|
+
#### **Example**
|
|
517
|
+
|
|
518
|
+
```JavaScript
|
|
519
|
+
// Generate messages for the Enigma Model I
|
|
520
|
+
function generateI(count, list) {
|
|
521
|
+
for (let idx = 0; idx < count; idx++) {
|
|
522
|
+
let message = generator.generateEncodedText({
|
|
523
|
+
rotors: ['I', 'II', 'III', 'IV', 'V'],
|
|
524
|
+
reflectors: ['A', 'B', 'C'],
|
|
525
|
+
})
|
|
526
|
+
list.push({model: 'I', ...message});
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
`generateEnigmaSetup(settings)`
|
|
532
|
+
|
|
533
|
+
Call this method to generate a random Enigma setup. This includes only the
|
|
534
|
+
configurable items, it does not include the details of the machine itself.
|
|
535
|
+
|
|
536
|
+
#### **Parameters**
|
|
537
|
+
- **settings** (optional), alternative configuration settings for the Enigma
|
|
538
|
+
- _rotors_ (optional) alternate list of rotors to choose from. This will
|
|
539
|
+
default to all defined rotors except those that are fixed.
|
|
540
|
+
_fixed_ (optional) an array of fixed rotors to choose one from. Defaults to
|
|
541
|
+
an empty list
|
|
542
|
+
|
|
543
|
+
#### **Returns**
|
|
544
|
+
the generated settings. This is an obejct with these fields
|
|
545
|
+
|
|
546
|
+
- **rotors** an array of three rotor names, four if fixed was given in the
|
|
547
|
+
settings
|
|
548
|
+
- **ringSettings** an array of offsets for the ring settings
|
|
549
|
+
- **plugs** 10 pairs of letters that will be used as connections on the plug
|
|
550
|
+
board
|
|
551
|
+
|
|
552
|
+
`generateKeySheet(days)`
|
|
553
|
+
|
|
554
|
+
Call this method to generate a monthly key sheet. This is the same data that
|
|
555
|
+
would have been used by officers to setup the Enigma every day. The keysheet
|
|
556
|
+
is generated for an M3 (rotors I-VIII) using reflector B
|
|
557
|
+
|
|
558
|
+
#### **Parameters**
|
|
559
|
+
- **days** The number of days to generate data for
|
|
560
|
+
|
|
561
|
+
#### **Returns**
|
|
562
|
+
the key sheet which is an array of objects, each one with these fields
|
|
563
|
+
|
|
564
|
+
- **day** the day of the month
|
|
565
|
+
- **rotors** an array of three rotor names
|
|
566
|
+
- **ringSettings** an array of offsets for the ring settings
|
|
567
|
+
- **plugs** 10 pairs of letters that will be used as connections on the plug
|
|
568
|
+
board
|
|
569
|
+
- **indicators** and array of four three-letter strings. These strings will be
|
|
570
|
+
unique across the key sheet
|
|
571
|
+
|
|
572
|
+
`generateMessages(sheet, count)`
|
|
573
|
+
|
|
574
|
+
Call this method to create an array of messages based off a key sheet. This has
|
|
575
|
+
the same informaton that a message in the field would possess. The construction
|
|
576
|
+
of the message follow the the standards of the German military beginning in
|
|
577
|
+
1940. They are as follows:
|
|
578
|
+
|
|
579
|
+
>The Wehrmacht radio operator sets each day the rotors, ring settings and
|
|
580
|
+
plugboard according to the key sheet. For each new message, he now selects new
|
|
581
|
+
randomly chosen start position or Grundstellung, say WZA, and a random message
|
|
582
|
+
key or Spruchschlüssel, say SXT. He moves the rotors to the random start
|
|
583
|
+
position WZA and encrypts the random message key SXT...
|
|
584
|
+
>
|
|
585
|
+
>He then sets message key SXT as start position of the rotors and encrypts the
|
|
586
|
+
actual message. Next, he transmits the random start position WZA, the encrypted
|
|
587
|
+
message key RSK and the Kenngruppe FDJKM together with his message.
|
|
588
|
+
>
|
|
589
|
+
>--[Enigma Message Procedures](https://www.ciphermachinesandcryptology.com/en/enigmaproc.htm)
|
|
590
|
+
|
|
591
|
+
The first five characters of each message was used to specify one of the four
|
|
592
|
+
key identifiers from the key sheet that defines the Enigma configuration. The
|
|
593
|
+
first two characters of this group were randomly chosen, and the last three were
|
|
594
|
+
one of the key identifiers for that daily setup. This text was not encrypted.
|
|
595
|
+
|
|
596
|
+
#### **Parameters**
|
|
597
|
+
- **sheet** a key sheet as generated from `generateKeySheet`
|
|
598
|
+
- **count** the number of messages to create
|
|
599
|
+
|
|
600
|
+
#### **Returns**
|
|
601
|
+
an array of messages. Each message is an array of sub messages. A message was
|
|
602
|
+
broken down into text blocks that were no longer than 250 characters and sent
|
|
603
|
+
in multiple parts. These sub messages were sent using a unique key and start
|
|
604
|
+
position. These are the fields in a sub message.
|
|
605
|
+
|
|
606
|
+
- **key** a randomly chosen key, this would be transmitted with the message
|
|
607
|
+
- **enc** the encoded start position for the message. This was encoded using
|
|
608
|
+
the randomly chosen key. This was sent with the message
|
|
609
|
+
- **text** the message text encoded using the unencoded start position. The
|
|
610
|
+
first five letters of this text string included the unencrypted key
|
|
611
|
+
identifier.
|
|
612
|
+
- **start** the unencoded start position. This was not sent with the message but
|
|
613
|
+
is included here to verify an implementation of this method.
|
|
614
|
+
- **clear** the unencrypted message. This can be used to verify an
|
|
615
|
+
implementation of this method.
|
|
616
|
+
|
|
617
|
+
#### **Example Message**
|
|
618
|
+
|
|
619
|
+
```json
|
|
620
|
+
[
|
|
621
|
+
{
|
|
622
|
+
"key": "YSR",
|
|
623
|
+
"enc": "MHH",
|
|
624
|
+
"start": "GJC",
|
|
625
|
+
"text": "OAYXJ CTCBV BZRBS SORIL YVMMM LLIVS OBUYU VMQTJ GFSZU XYUDR GHKRX KRCDV QEZCH MDTAJ KZUXV TZPOA VSCFH ILWQC DJNAH PILTN MMLHK OULDS QIMCB NMTRZ OQFQY CVWVW QXEHU WCMKJ XGUSA YPBIE EXGKZ LZLUF NMJNB ISUWN DYOWW XUJNK VUYOV SJOSW MQNSP MUTAZ DQIXV RGJXM ",
|
|
626
|
+
"clear": "WHATD EVILW ASTTH ATTHU SHATH COZEN DYOUA THOOD MANBL INDEY ESWIT HOUTF EELIN GFEEL INGWI THOUT SIGHT EARSW ITHOU THAND SOREY ESSME LLING SANSA LLORB UTASI CKLYP ARTOF ONETR UESEN SECOU LDNOT SOMOP EOSHA MEWHE REIST HYBLU SHREB ELLIO USHEL LIFTH"
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"key": "MYR",
|
|
630
|
+
"enc": "AJI",
|
|
631
|
+
"start": "ETH",
|
|
632
|
+
"text": "OAYXJ WPIFA NPUKR ZWSZG GXYZX ZYTMQ PHVNB CPHUA XEUVC VOGUZ LPQSP RFHTK ZNFHL OYGEU ZGOPG EFBTL ORNDH INNGD LDIAT DDPOP QZZKE XBUWI VCJOW LWDJO BLASV JTOMG LUDRC LIISC DJZES QZSSD GBYSG PUGHS EWADO KDSFP ZOLBL RPEYX YKQTF HOI",
|
|
633
|
+
"clear": "OUCAN STMUT INEIN AMATR ONSBO NESTO FLAMI NGYOU THLET VIRTU EBEAS WAXAN DMELT INHER OWNFI REPRO CLAIM NOSHA MEWHE NTHEC OMPUL SIVEA RDOUR GIVES THECH ARGES INCEF ROSTI TSELF ASACT IVELY DOTHB URNAN DREAS ONPAN DERSW ILL"
|
|
634
|
+
}
|
|
635
|
+
]
|
|
636
|
+
```
|
package/enigma-logo.jpg
ADDED
|
Binary file
|