@ondoher/enigma 0.1.7 → 1.0.0
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 +454 -93
- package/bin/enigma.js +0 -0
- package/jsconfig.json +3 -0
- package/lib/enigma/Encoder.js +12 -13
- package/lib/enigma/Enigma.js +68 -50
- package/lib/enigma/EnigmaTypes.d.ts +101 -0
- package/lib/enigma/EntryDisc.js +13 -5
- package/lib/enigma/Inventory.js +26 -6
- package/lib/enigma/PlugBoard.js +20 -17
- package/lib/enigma/Reflector.js +4 -11
- package/lib/enigma/Rotor.js +5 -35
- package/lib/enigma/standardInventory.js +2 -2
- package/lib/enigma/tests/EnigmaSpec.js +0 -5
- package/lib/enigma/tests/PlugBoardSpec.js +15 -14
- package/lib/enigma/tests/RotorSpec.js +1 -1
- package/lib/generator/CodeBook.js +180 -0
- package/lib/generator/Generator.js +94 -386
- package/lib/generator/GeneratorTypes.d.ts +100 -0
- package/lib/generator/index.js +2 -0
- package/lib/utils/Random.js +236 -0
- package/package.json +10 -3
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class implements a pseudorandom number generator that can be given a
|
|
3
|
+
* seed to produce a consistent sequence of numbers. This algorithm is
|
|
4
|
+
* inappropriate for real cryptographic purposes, but allows the production of
|
|
5
|
+
* output that can be consistently reproduced.
|
|
6
|
+
*
|
|
7
|
+
* This algorithm was stolen from the product Delphi.
|
|
8
|
+
*/
|
|
9
|
+
class Random {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.randSeed = Date.now();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Call this method to set the seed value for the randomizer. The initial value
|
|
16
|
+
* will be the current time in milliseconds.
|
|
17
|
+
*
|
|
18
|
+
* @param {Number} value for the seed,
|
|
19
|
+
*/
|
|
20
|
+
randomize(value) {
|
|
21
|
+
value = (value === undefined) ? Date.now() : value;
|
|
22
|
+
|
|
23
|
+
this.randSeed = value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Call this method to get a random number. If passed a value, the return
|
|
28
|
+
* will be an integer between 0 and that number - 1. without it will be a
|
|
29
|
+
* decimal value between 0 and < 1.
|
|
30
|
+
*
|
|
31
|
+
* @param {Number} [limit] if passed the upper boundary of the integer - 1
|
|
32
|
+
*
|
|
33
|
+
* @returns {Number} the randomized value as either an integer or a decimal
|
|
34
|
+
* value depending on how it was called.
|
|
35
|
+
*/
|
|
36
|
+
random(limit)
|
|
37
|
+
{
|
|
38
|
+
let randPow = Math.pow(2, -31);
|
|
39
|
+
let randLimit = Math.pow(2, 31);
|
|
40
|
+
let magic = 0x8088405;
|
|
41
|
+
let rand = this.randSeed * magic + 1;
|
|
42
|
+
|
|
43
|
+
this.randSeed = rand % randLimit
|
|
44
|
+
|
|
45
|
+
rand = rand % randLimit
|
|
46
|
+
rand = rand * randPow;
|
|
47
|
+
|
|
48
|
+
if (limit) {
|
|
49
|
+
rand = Math.floor(Math.abs(rand) * limit);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return rand;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Generate a random number using a bell curve. The curve is created using
|
|
57
|
+
* the analogy of dice. For example, a random number built with two six
|
|
58
|
+
* sided dice will have the peak of the curve at 7 with 2 and 12 being at
|
|
59
|
+
* the bottom.
|
|
60
|
+
*
|
|
61
|
+
* @param {number} dice - how many random numbers to pick
|
|
62
|
+
* @param {number} faces - the range, from 1 - faces, of the number
|
|
63
|
+
* @param {boolean} [zeroBased] - if true, the random range for each die will be from 0 - faces-1
|
|
64
|
+
*
|
|
65
|
+
* @return {number} the random number
|
|
66
|
+
*/
|
|
67
|
+
randomCurve(dice, faces, zeroBased = false) {
|
|
68
|
+
let result = 0;
|
|
69
|
+
let adjust = zeroBased ? 0 : 1
|
|
70
|
+
for (let idx = 0; idx < dice; idx++) {
|
|
71
|
+
result += this.random(faces) + adjust;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* call this method to pick a random number from an array and remove it
|
|
79
|
+
*
|
|
80
|
+
* @template T
|
|
81
|
+
* @param {T[]} list the array of items to choose from
|
|
82
|
+
*
|
|
83
|
+
* @returns {T} the chosen item
|
|
84
|
+
*/
|
|
85
|
+
pickOne(list) {
|
|
86
|
+
let pos = Math.floor(this.random() * list.length);
|
|
87
|
+
let choice = list.splice(pos, 1);
|
|
88
|
+
return choice[0];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Call this method to pick two items from a given list. The items are
|
|
93
|
+
* removed from the array. If the array is less than two items then it
|
|
94
|
+
* will return either an empty array or an array with one element.
|
|
95
|
+
*
|
|
96
|
+
* @template T
|
|
97
|
+
*
|
|
98
|
+
* @param {T[]} list the array of items to choose
|
|
99
|
+
* @returns {T[]} the two chosen items
|
|
100
|
+
*/
|
|
101
|
+
pickPair(list) {
|
|
102
|
+
if (list.length === 0) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (list.length === 1) {
|
|
107
|
+
return [this.pickOne(list)];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return [
|
|
111
|
+
this.pickOne(list),
|
|
112
|
+
this.pickOne(list)
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Call this method to choose a given number of items from a list. The items
|
|
118
|
+
* are removed.
|
|
119
|
+
*
|
|
120
|
+
* @template T
|
|
121
|
+
*
|
|
122
|
+
* @param {Number} count the number of items to pick
|
|
123
|
+
* @param {T[]} list the list of items to choose from
|
|
124
|
+
*
|
|
125
|
+
* @returns {T[]} the chosen items
|
|
126
|
+
*/
|
|
127
|
+
pick(count, list) {
|
|
128
|
+
let result = [];
|
|
129
|
+
let limit = Math.min(list.length, count)
|
|
130
|
+
for(let idx = 0; idx < limit; idx++) {
|
|
131
|
+
result.push(this.pickOne(list));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Call this method to randomly pick a set of item pairs. The items
|
|
140
|
+
* will be removed from the list.
|
|
141
|
+
*
|
|
142
|
+
* @template T
|
|
143
|
+
* @param {Number} count the number of pairs to pick
|
|
144
|
+
* @param {T[]} list the list of items to choose from
|
|
145
|
+
*,
|
|
146
|
+
* @returns {T[][]}} the item pairs chosen. Each pair is an array of
|
|
147
|
+
* two items from the list
|
|
148
|
+
*/
|
|
149
|
+
pickPairs(count, list) {
|
|
150
|
+
/** @type {[T, T][]} */
|
|
151
|
+
let result = [];
|
|
152
|
+
|
|
153
|
+
for(let idx = 0; idx < count; idx++) {
|
|
154
|
+
result.push(this.pickPair(list));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Call this method to chose a random item from a list. The item is not
|
|
162
|
+
* removed.
|
|
163
|
+
*
|
|
164
|
+
* @template T
|
|
165
|
+
*
|
|
166
|
+
* @param {T[]} list the list of items to choose from
|
|
167
|
+
* @returns {T} the chosen item
|
|
168
|
+
*/
|
|
169
|
+
chooseOne(list) {
|
|
170
|
+
let pos = Math.floor(this.random() * list.length);
|
|
171
|
+
return list[pos];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Call this method to pick a pair of items from the given list. The items
|
|
176
|
+
* are guaranteed to be unique.
|
|
177
|
+
*
|
|
178
|
+
* @template T
|
|
179
|
+
*
|
|
180
|
+
* @param {T[]} list - the list of items
|
|
181
|
+
* @returns {T[]}
|
|
182
|
+
*/
|
|
183
|
+
choosePair(list) {
|
|
184
|
+
if (list.length < 2) {
|
|
185
|
+
return list;
|
|
186
|
+
}
|
|
187
|
+
let first = Math.floor(this.random() * list.length);
|
|
188
|
+
let second = Math.floor(this.random() * list.length);
|
|
189
|
+
|
|
190
|
+
while (second === first) {
|
|
191
|
+
second = Math.floor(this.random() * list.length);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return [list[first], list[second]];
|
|
195
|
+
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Call this method to return a random list of contiguous items from the
|
|
200
|
+
* given list. The items are not removed.
|
|
201
|
+
*
|
|
202
|
+
* @template T
|
|
203
|
+
* @param {number} count
|
|
204
|
+
* @param {T[]} list
|
|
205
|
+
*
|
|
206
|
+
* return {T[]}
|
|
207
|
+
*/
|
|
208
|
+
chooseRange(count, list) {
|
|
209
|
+
let start = this.random(list.length) - count;
|
|
210
|
+
|
|
211
|
+
return list.slice(start, start + count).join(' ');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Call this method to randomly pick a subset of items from a list. The
|
|
216
|
+
* items are not removed.
|
|
217
|
+
*
|
|
218
|
+
* @template T
|
|
219
|
+
*
|
|
220
|
+
* @param {Number} count the number of items to choose
|
|
221
|
+
* @param {T[]} list the list of items to choose from
|
|
222
|
+
*
|
|
223
|
+
* @returns {T[]} the list of items chosen
|
|
224
|
+
*/
|
|
225
|
+
choose(count, list){
|
|
226
|
+
let result = [];
|
|
227
|
+
for(let idx = 0; idx < count; idx++) {
|
|
228
|
+
result.push(this.chooseOne(list));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
export default new Random();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ondoher/enigma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Tools and documentation to help in building and testing an Enigma Machine simulator.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -8,10 +8,17 @@
|
|
|
8
8
|
},
|
|
9
9
|
"author": "Glenn Anderson",
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"keywords": [
|
|
11
|
+
"keywords": [
|
|
12
|
+
"enigma",
|
|
13
|
+
"enigma-machine",
|
|
14
|
+
"enigma machine",
|
|
15
|
+
"enigma codebook",
|
|
16
|
+
"simulation",
|
|
17
|
+
"cryptography"
|
|
18
|
+
],
|
|
12
19
|
"repository": {
|
|
13
20
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/Ondoher/enigma.git",
|
|
21
|
+
"url": "git+https://github.com/Ondoher/enigma.git",
|
|
15
22
|
"directory": "package"
|
|
16
23
|
},
|
|
17
24
|
"homepage": "https://github.com/Ondoher/enigma#readme",
|