@ondoher/enigma 1.0.2 → 1.0.5

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.
Files changed (49) hide show
  1. package/README.md +75 -48
  2. package/dist/index.d.ts +899 -0
  3. package/jsconfig.json +7 -1
  4. package/lib/enigma/Encoder.js +154 -12
  5. package/lib/enigma/Enigma.js +45 -59
  6. package/lib/enigma/EnigmaTypes.d.ts +115 -18
  7. package/lib/enigma/EntryDisc.js +2 -8
  8. package/lib/enigma/PlugBoard.js +4 -9
  9. package/lib/enigma/Reflector.js +5 -9
  10. package/lib/enigma/Rotor.js +43 -36
  11. package/lib/enigma/index.js +1 -1
  12. package/lib/enigma/tests/EnigmaSpec.js +21 -15
  13. package/lib/enigma/tests/RotorData.js +1 -1
  14. package/lib/enigma/tests/RotorSpec.js +3 -1
  15. package/lib/generator/CodeBook.js +3 -3
  16. package/lib/generator/Generator.js +6 -5
  17. package/lib/generator/GeneratorTypes.d.ts +2 -1
  18. package/lib/utils/Random.js +1 -1
  19. package/package.json +8 -2
  20. package/scripts/EnigmaData.js +236 -0
  21. package/scripts/hamlet.html +8880 -0
  22. package/scripts/make-validated-data.js +4 -0
  23. package/scripts/parseHamlet.js +32 -0
  24. package/scripts/test-messages.js +60 -0
  25. package/scripts/test.js +118 -0
  26. package/scripts/x +6446 -0
  27. package/tsconfig.json +19 -0
  28. package/types/enigma/Encoder.d.ts +128 -0
  29. package/types/enigma/Enigma.d.ts +88 -0
  30. package/types/enigma/EntryDisc.d.ts +17 -0
  31. package/types/enigma/Inventory.d.ts +91 -0
  32. package/types/enigma/PlugBoard.d.ts +26 -0
  33. package/types/enigma/Reflector.d.ts +14 -0
  34. package/types/enigma/Rotor.d.ts +59 -0
  35. package/types/enigma/consts.d.ts +1 -0
  36. package/types/enigma/index.d.ts +5 -0
  37. package/types/enigma/standardInventory.d.ts +71 -0
  38. package/types/enigma/tests/EnigmaData.d.ts +46 -0
  39. package/types/enigma/tests/EnigmaSpec.d.ts +1 -0
  40. package/types/enigma/tests/PlugBoardData.d.ts +4 -0
  41. package/types/enigma/tests/PlugBoardSpec.d.ts +1 -0
  42. package/types/enigma/tests/RotorData.d.ts +15 -0
  43. package/types/enigma/tests/RotorSpec.d.ts +1 -0
  44. package/types/generator/CodeBook.d.ts +82 -0
  45. package/types/generator/Generator.d.ts +67 -0
  46. package/types/generator/hamlet.d.ts +2 -0
  47. package/types/generator/index.d.ts +3 -0
  48. package/types/index.d.ts +899 -0
  49. package/types/utils/Random.d.ts +131 -0
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outFile": "./dist/index.d.ts",
4
+ "module": "AMD",
5
+ "target": "es2020",
6
+ "allowJs": true, /* Allow JavaScript files to be compiled. */
7
+ "checkJs": true, /* Report errors in .js files. */
8
+ "declaration": true, /* Generate .d.ts files for JS files. */
9
+ "emitDeclarationOnly": true, /* Only emit .d.ts files, not the source .js files. */
10
+ "outDir": "./types", /* Redirect output to the 'types' folder. */
11
+ "paths": {
12
+ "undici-types": [
13
+ "./node_modules/undici-types/index.d.ts"
14
+ ]
15
+ }
16
+ },
17
+ "include": ["lib/**/*.js", "lib/**/*.d.ts"], /* Specify which JS files to include (e.g., in a 'src' directory). */
18
+ "exclude": ["node_modules"], /* Exclude standard folders. */
19
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * This is the base class for an encoder. The default implementation of the
3
+ * encode method is to return the input as the output
4
+ */
5
+ export default class Encoder {
6
+ /**
7
+ * Constructor for the base encoder
8
+ *
9
+ * @param {string} name
10
+ * @param {ComponentType} type
11
+ * @param {EncoderSetup} settings
12
+ */
13
+ constructor(name: string, type: ComponentType, settings: EncoderSetup);
14
+ name: string;
15
+ type: ComponentType;
16
+ alphabet: string;
17
+ contactCount: number;
18
+ /** @type {{[name: string]: Listener}} */
19
+ listeners: {
20
+ [name: string]: Listener;
21
+ };
22
+ /**
23
+ * given a connector number, normalize it to be between 0 and 25 inclusive.
24
+ *
25
+ * @param {Number} connector the connector being normalized
26
+ *
27
+ * @returns {Number} value between 0 and 25
28
+ */
29
+ normalize(connector: number): number;
30
+ /**
31
+ *
32
+ * @param {string} letter
33
+ *
34
+ * @returns {boolean}
35
+ */
36
+ verifyLetter(letter: string): boolean;
37
+ /**
38
+ * Call this method to convert a letter to a connector value
39
+ *
40
+ * @param {string} letter
41
+ * @returns {number | undefined}
42
+ */
43
+ letterToConnector(letter: string): number | undefined;
44
+ /**
45
+ * Call this method to turn a connector to a letter value
46
+ *
47
+ * @param {number} connector
48
+ * @returns {string | undefined}
49
+ */
50
+ connectorToLetter(connector: number): string | undefined;
51
+ /**
52
+ * Given an alphabetic connection map, convert that into an array of
53
+ * numbers. The index into the array or string is the input connector, and
54
+ * the value at that position is the output connector
55
+ *
56
+ * @param {String} map connections map.
57
+ * @returns {Array.<Number>} the numerical map
58
+ */
59
+ makeMap(map: string): Array<number>;
60
+ /**
61
+ * given an existing connection map from input to out put, create a new map
62
+ * that has the connections going in the other direction, output to input.
63
+ *
64
+ * @param {Array.<Number>} map connection map
65
+ * @returns {Array.<Number>} the reversed map
66
+ */
67
+ makeReverseMap(map: Array<number>): Array<number>;
68
+ /**
69
+ * Call this method to convert the input connector number to the output in
70
+ * the given direction The default encode method just passes the input value
71
+ * through
72
+ *
73
+ * @param {Direction} _direction either right for moving towards the reflector
74
+ * or left if moving back
75
+ * @param {Number} input the specific connection receiving an input
76
+ *
77
+ * @returns {Number} The translated output connector number
78
+ */
79
+ encode(_direction: Direction, input: number): number;
80
+ /**
81
+ *
82
+ * @param {number | string} input
83
+ * @param {Direction} direction
84
+ */
85
+ fireInput(input: number | string, direction: Direction): void;
86
+ /**
87
+ *
88
+ * @param {number | string} output
89
+ * @param {Direction} direction
90
+ */
91
+ fireOutput(output: number | string, direction: Direction): void;
92
+ /**
93
+ *
94
+ * @param {number | string} input
95
+ * @param {number | string} output
96
+ * @param {Direction} direction
97
+ */
98
+ fireTranslate(input: number | string, output: number | string, direction: Direction): void;
99
+ /**
100
+ *
101
+ * @param {number | string} input
102
+ * @param {number | string} output
103
+ * @param {Direction} direction
104
+ */
105
+ fireEncodeSet(input: number | string, output: number | string, direction: Direction): void;
106
+ /**
107
+ * Call this method to add a function to be called when important events
108
+ * happen to a component. The name can be used to later remove the listener
109
+ *
110
+ * @param {string} name - the name of the listener
111
+ * @param {Listener} cb - the function to be called.
112
+ */
113
+ listen(name: string, cb: Listener): void;
114
+ /**
115
+ * Call this method to remove a listener
116
+ *
117
+ * @param {string} name - the name of the listener
118
+ */
119
+ unlisten(name: string): void;
120
+ /**
121
+ * Call this method to call any event listeners
122
+ *
123
+ * @param {EventName} event - the event being fired
124
+ * @param {String} name - the name of the component firing the event
125
+ * @param {EventData} data - the event data
126
+ */
127
+ fire(event: EventName, name: string, data: EventData): void;
128
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Construct this class to get a new instance of the Enigma. Many of the
3
+ * parameters to the constructor and the config method reference the names of
4
+ * standard Enigma parts. These are retrieved from the Inventory instance
5
+ */
6
+ export default class Enigma extends Encoder {
7
+ /**
8
+ * The constructor for the Enigma. This represents the unconfigurable
9
+ * settings of the device.
10
+ *
11
+ * @param {string} name
12
+ * @param {EnigmaSetup} settings
13
+ */
14
+ constructor(name: string, settings: EnigmaSetup);
15
+ plugboard: PlugBoard;
16
+ entryDisc: EntryDisc;
17
+ reflector: Reflector;
18
+ length: number;
19
+ /** @type {Rotor[]} */
20
+ _rotors: Rotor[];
21
+ /** @type {{[rotor: number]: boolean}} */
22
+ pending: {
23
+ [rotor: number]: boolean;
24
+ };
25
+ /** @type {Encoder[]} */
26
+ encoders: Encoder[];
27
+ /**@type {SimplifiedConfiguration & {reflector: string}} */
28
+ _configuration: SimplifiedConfiguration & {
29
+ reflector: string;
30
+ };
31
+ /**
32
+ * the configured rotors
33
+ *
34
+ * @return {Rotor[]}
35
+ */
36
+ get rotors(): Rotor[];
37
+ /**
38
+ * @returns {SimplifiedConfiguration & {reflector: string}}
39
+ */
40
+ get configuration(): SimplifiedConfiguration & {
41
+ reflector: string;
42
+ };
43
+ /**
44
+ * Configure the Enigma for encoding.
45
+ *
46
+ * @param {EnigmaConfiguration} settings - the configuration of the Enigma.
47
+ * These settings represent the aspects of the Enigma that can can change for daily
48
+ * configuration.
49
+ */
50
+ configure(settings: EnigmaConfiguration): void;
51
+ /**
52
+ * Call this method to "step" the rotors one time. This method will manage the
53
+ * stepping between all rotors
54
+ */
55
+ step(): void;
56
+ /**
57
+ * Call this method to set the starting rotation for the messages to encrypt
58
+ *
59
+ * @param {number[]|string} setup - length of the string or the array
60
+ * should match the number of rotors and are given left to right. If start
61
+ * is a string then the letters of the string specify the start value seen
62
+ * in the window for the corresponding rotor. If it is an array then each
63
+ * number will be the one-based rotation.
64
+ */
65
+ setStart(setup: number[] | string): void;
66
+ /**
67
+ * Call this method to simulate a keypress on the Enigma. This will output
68
+ * the encoded letter
69
+ *
70
+ * @param {String} letter the key pressed
71
+ * @returns {String | undefined} the encoded letter
72
+ */
73
+ keyPress(letter: string): string | undefined;
74
+ /**
75
+ * Call this shortcut method to encode a whole string
76
+ *
77
+ * @param {String} start the starting position for the rotors
78
+ * @param {String} text the text to encode
79
+ *
80
+ * @returns {String} the encoded string.
81
+ */
82
+ translate(start: string, text: string): string;
83
+ }
84
+ import Encoder from "./Encoder.js";
85
+ import PlugBoard from "./PlugBoard.js";
86
+ import EntryDisc from "./EntryDisc.js";
87
+ import Reflector from "./Reflector.js";
88
+ import Rotor from "./Rotor.js";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * This is the class for an entry disc. Entry discs are fixed disks of connector
3
+ * pins.
4
+ */
5
+ export default class EntryDisc extends Encoder {
6
+ /**
7
+ * Constructor for the entry disc.
8
+ *
9
+ * @param {String} name the name of this entry disc
10
+ * @param {EncoderSetup} settings contains the alphabet being used, and the map
11
+ * between input and output contacts
12
+ */
13
+ constructor(name: string, settings: EncoderSetup);
14
+ rightMap: number[];
15
+ leftMap: number[];
16
+ }
17
+ import Encoder from './Encoder.js';
@@ -0,0 +1,91 @@
1
+ declare const _default: Inventory;
2
+ export default _default;
3
+ /**
4
+ * This is the class used to manage the standard inventory of components. An
5
+ * instance of this class is exported as the default of this module
6
+ */
7
+ declare class Inventory {
8
+ entryDiscs: {};
9
+ /** @type {{[name: string]: RouterInventorySpec}}*/
10
+ rotors: {
11
+ [name: string]: RouterInventorySpec;
12
+ };
13
+ reflectors: {};
14
+ /**
15
+ * Call this method to add a new Rotor type to the inventory.
16
+ *
17
+ * @param {String} name the name of the rotor being added. This name will be
18
+ * used when specifying the rotors to use for the Enigma configuration.
19
+ * @param {String} map a string specifying the connector mapping. The index
20
+ * of the string is the logical coordinate of the connector, the character
21
+ * at that index is the output connector. To be exact, it would be the
22
+ * position of that character in the given alphabet. So, in the map '
23
+ * EKMFLGDQVZNTOWYHXUSPAIBRCJ', input connector 0 would map to output
24
+ * connector 4 and input connector 1 would map to output connector 10.
25
+ * Remember that the connectors are numbered starting at 0.
26
+ * @param {String} turnovers this is a string of characters representing the
27
+ * turnover locations on the disk. These letter would be the value shown in
28
+ * the window to during turnover. In Rotor I this is 'Q' in rotors VI, VII,
29
+ * and VIII there are two turnover locations, 'M' and 'Z'. Pass an empty
30
+ * string if this is a fixed rotor
31
+ */
32
+ addRotor(name: string, map: string, turnovers: string): void;
33
+ /**
34
+ * Call this method to add a new reflector definition.
35
+ *
36
+ * @param {String} name this is the name that will be used to reference this
37
+ * reflector when constructing an Enigma class.
38
+ * @param {String} map the mapping between connectors. this uses the same
39
+ * format used in the addRotor method
40
+ */
41
+ addReflector(name: string, map: string): void;
42
+ /**
43
+ * Call this method to add a new entry disc. There was only one used in the
44
+ * standard military models, but there were other versions that defined it
45
+ * differently.
46
+ *
47
+ * @param {*} name this is the name that will be used to reference this
48
+ * entry disc when constructing an Enigma class.
49
+ * @param {*} map the mapping between connectors. this uses the same format
50
+ * used in the addRotor method
51
+ */
52
+ addEntryDisc(name: any, map: any): void;
53
+ /**
54
+ * Call this method to get the setup for a defined rotor.
55
+ *
56
+ * @param {String} name the name of the rotor as it was added to the
57
+ * inventory.
58
+ *
59
+ * @returns {Object} the rotor definition
60
+ * @property {String} map the connection map for the rotor
61
+ * @property {String} turnovers the locations where turnovers happen
62
+ */
63
+ getRotor(name: string): any;
64
+ /**
65
+ * Call this method to get the setup for a defined reflector.
66
+ *
67
+ * @param {String} name the name of the reflector as it was added to the
68
+ * inventory.
69
+ * @returns {Object} the reflector definition
70
+ * @property {String} the connection map for the reflector
71
+ */
72
+ getReflector(name: string): any;
73
+ /**
74
+ * Call this method to get the setup for a defined entry disc.
75
+ *
76
+ * @param {String} name the name of the entry disc as it was added to the
77
+ * inventory.
78
+ * @returns {Object} the entry disc definition
79
+ * @property {String} the connection map for the entry disc
80
+ */
81
+ getEntryDisc(name: string): any;
82
+ /**
83
+ * Call this method to get the names of all the rotors in the inventory
84
+ *
85
+ * @param {boolean} [fixed] - if specified it returns only the names of
86
+ * routers filtered on if they are fixed or not, otherwise it returns all
87
+ *
88
+ * @returns {string[]} the names of the rotors
89
+ */
90
+ getRotorNames(fixed?: boolean): string[];
91
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * This class represents the plugboard. There is only one type of plugboard
3
+ */
4
+ export default class PlugBoard extends Encoder {
5
+ /**
6
+ * Constructor for the plugboard.
7
+ *
8
+ * @param {String} name the name for the plugboard, defaults to 'plugboard'
9
+ * @param {EncoderSetup} [settings] the settings for the plugboard. Only needed if
10
+ * using an alternate alphabet
11
+ */
12
+ constructor(name?: string, settings?: EncoderSetup);
13
+ map: string;
14
+ rightMap: any[];
15
+ leftMap: any[];
16
+ plugs: string;
17
+ /**
18
+ * Call this method to configure the plug board. This will be used to
19
+ * provide the plug connections
20
+ *
21
+ * @param {Plugs} plugs the configuration options for the plug
22
+ * board
23
+ */
24
+ configure(plugs?: Plugs): void;
25
+ }
26
+ import Encoder from "./Encoder.js";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Make in instance of this class to construct a reflector
3
+ */
4
+ export default class Reflector extends Encoder {
5
+ /**
6
+ * constructor for the reflector class.
7
+ *
8
+ * @param {String} name the name of the reflector instance
9
+ * @param {EncoderSetup} settings The definition of the reflector
10
+ */
11
+ constructor(name: string, settings: EncoderSetup);
12
+ map: number[];
13
+ }
14
+ import Encoder from './Encoder.js';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Create an instance of this class to construct a Rotor object. The Rotor class
3
+ * encapsulates many of the peculiar behaviors of the Enigma. All connector
4
+ * values here are specified in physical space.
5
+ */
6
+ export default class Rotor extends Encoder {
7
+ /**
8
+ * This is the constructor for the rotor.
9
+ *
10
+ * @param {String} name the name of the rotor; under normal circumstances
11
+ * this will be the string 'rotor-' plus the standard name for the rotor,
12
+ * for example 'rotor-IV'
13
+ * @param {RotorSetup} settings an object that contains the various options that
14
+ * define the the rotor and how it is configured.
15
+ */
16
+ constructor(name: string, settings: RotorSetup);
17
+ map: string[];
18
+ rightMap: number[];
19
+ leftMap: number[];
20
+ length: number;
21
+ ringOffset: number;
22
+ turnoverLookup: number[];
23
+ offset: number;
24
+ fixed: boolean;
25
+ turnovers: string;
26
+ _turnovers: Set<number>;
27
+ /**
28
+ * Call this method to select the initial rotation of the rotor. This is a
29
+ * letter offset from the logical 0 connector. The initial rotation will
30
+ * also take into account the ring setting
31
+ *
32
+ * @param {String} connector This is a letter value that corresponds to what
33
+ * would appear in the rotation window. This value will be adjusted for the
34
+ * ring setting.
35
+ */
36
+ setStartPosition(connector: string): void;
37
+ /**
38
+ * Call this method to step the rotor
39
+ *
40
+ * @returns {Boolean} true if the next rotor should be stepped
41
+ */
42
+ step(): boolean;
43
+ /**
44
+ * Call this method to see if the next step on this rotor will lead to
45
+ * turnover. The Enigma class will call this on the middle rotor to handle
46
+ * double stepping.
47
+ *
48
+ * @returns true if this rotor will turnover on the next step
49
+ */
50
+ willTurnover(): boolean;
51
+ shouldTurnover(): boolean;
52
+ /**
53
+ * Call this method to find whether this is a fixed rotor. This is used for
54
+ * the non stepping rotors--beta and gamma--that are used in the M4
55
+ * @returns
56
+ */
57
+ isFixed(): boolean;
58
+ }
59
+ import Encoder from "./Encoder.js";
@@ -0,0 +1 @@
1
+ export const STANDARD_ALPHABET: string;
@@ -0,0 +1,5 @@
1
+ export { default as Enigma } from "./Enigma.js";
2
+ export { default as EntryDisc } from "./EntryDisc.js";
3
+ export { default as inventory } from "./Inventory.js";
4
+ export { default as PlugBoard } from "./PlugBoard.js";
5
+ export { default as Reflector } from "./Rotor.js";
@@ -0,0 +1,71 @@
1
+ export namespace entryDiscDefinitions {
2
+ let _default: string;
3
+ export { _default as default };
4
+ }
5
+ export namespace rotorDefinitions {
6
+ namespace I {
7
+ let map: string;
8
+ let turnovers: string;
9
+ }
10
+ namespace II {
11
+ let map_1: string;
12
+ export { map_1 as map };
13
+ let turnovers_1: string;
14
+ export { turnovers_1 as turnovers };
15
+ }
16
+ namespace III {
17
+ let map_2: string;
18
+ export { map_2 as map };
19
+ let turnovers_2: string;
20
+ export { turnovers_2 as turnovers };
21
+ }
22
+ namespace IV {
23
+ let map_3: string;
24
+ export { map_3 as map };
25
+ let turnovers_3: string;
26
+ export { turnovers_3 as turnovers };
27
+ }
28
+ namespace V {
29
+ let map_4: string;
30
+ export { map_4 as map };
31
+ let turnovers_4: string;
32
+ export { turnovers_4 as turnovers };
33
+ }
34
+ namespace VI {
35
+ let map_5: string;
36
+ export { map_5 as map };
37
+ let turnovers_5: string;
38
+ export { turnovers_5 as turnovers };
39
+ }
40
+ namespace VII {
41
+ let map_6: string;
42
+ export { map_6 as map };
43
+ let turnovers_6: string;
44
+ export { turnovers_6 as turnovers };
45
+ }
46
+ namespace VIII {
47
+ let map_7: string;
48
+ export { map_7 as map };
49
+ let turnovers_7: string;
50
+ export { turnovers_7 as turnovers };
51
+ }
52
+ namespace Beta {
53
+ let map_8: string;
54
+ export { map_8 as map };
55
+ let turnovers_8: string;
56
+ export { turnovers_8 as turnovers };
57
+ }
58
+ namespace Gamma {
59
+ let map_9: string;
60
+ export { map_9 as map };
61
+ let turnovers_9: string;
62
+ export { turnovers_9 as turnovers };
63
+ }
64
+ }
65
+ export const reflectorDefinitions: {
66
+ A: string;
67
+ B: string;
68
+ C: string;
69
+ 'Thin-B': string;
70
+ 'Thin-C': string;
71
+ };
@@ -0,0 +1,46 @@
1
+ export namespace enigmaData {
2
+ let sampleFieldMessages: ({
3
+ source: string;
4
+ model: string;
5
+ setup: {
6
+ reflector: string;
7
+ rotors: string[];
8
+ ringSettings: number[];
9
+ plugs: string;
10
+ };
11
+ message: {
12
+ key: string;
13
+ encoded: string;
14
+ decoded: string;
15
+ };
16
+ } | {
17
+ source: string;
18
+ model: string;
19
+ setup: {
20
+ reflector: string;
21
+ rotors: string[];
22
+ ringSettings: string;
23
+ plugs: string;
24
+ };
25
+ message: {
26
+ key: string;
27
+ encoded: string;
28
+ decoded: string;
29
+ };
30
+ })[];
31
+ let sampleVerifiedMessages: {
32
+ verified: string[];
33
+ model: string;
34
+ setup: {
35
+ rotors: string[];
36
+ plugs: string;
37
+ ringSettings: number[];
38
+ reflector: string;
39
+ };
40
+ message: {
41
+ key: string;
42
+ encoded: string;
43
+ decoded: string;
44
+ };
45
+ }[];
46
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export namespace plugBoardData {
2
+ let alphabet: string;
3
+ let plugSettings: string;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ export namespace rotorData {
2
+ namespace createData {
3
+ let alphabet: string;
4
+ let map: string;
5
+ let reverseMap: number[];
6
+ let turnovers: string;
7
+ let turnoversMap: number[];
8
+ }
9
+ namespace I {
10
+ let map_1: string;
11
+ export { map_1 as map };
12
+ let turnovers_1: string;
13
+ export { turnovers_1 as turnovers };
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ export {};