rotor_machine 1.1.1 → 1.2.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.
- checksums.yaml +4 -4
- data/README.md +94 -69
- data/lib/rotor_machine/session.rb +161 -0
- data/lib/rotor_machine/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 547ab156c985ce0df5dad34665d7705456ff34993b84cc738c887fce7144783f
|
4
|
+
data.tar.gz: 6d2211b04113a15757706928e3b572bc09bd2781036fb0317344984f774bd82e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3d3e224d89bdc1531cfe50f40cf66cec543b693da2547ebf4fd4a3892fc125f5a86c60c96d0912c0161f28e2c353772a5987da99a1d2872d2ee163e49616321
|
7
|
+
data.tar.gz: a85cec802ad9a032b8348f5311bd686428d8e23c183182db4dcf9827c831d272b4bb2df1d14716e3749b94928c7c9fd7920d98b18d649ffd6db947d73b17ecf4
|
data/README.md
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|

|
4
4
|
|
5
|
-
The `RotorMachine` gem provides a simple Ruby implementation of the
|
5
|
+
The `RotorMachine` gem provides a simple Ruby implementation of the
|
6
6
|
[Enigma](https://en.wikipedia.org/wiki/Enigma_machine) rotor encryption machine.
|
7
7
|
|
8
|
-
I wrote RotorMachine primarily as an exercise in Test-Driven Development with
|
9
|
-
RSpec. It is not intended to be efficient or performant, and I wasn't striving much
|
10
|
-
for idiomatic conciseness. My aims were fairly modular code and a relatively
|
8
|
+
I wrote RotorMachine primarily as an exercise in Test-Driven Development with
|
9
|
+
RSpec. It is not intended to be efficient or performant, and I wasn't striving much
|
10
|
+
for idiomatic conciseness. My aims were fairly modular code and a relatively
|
11
11
|
complete RSpec test suite.
|
12
12
|
|
13
|
-
Many thanks to Kevin Sylvestre, whose
|
14
|
-
[blog post](https://ksylvest.com/posts/2015-01-03/the-enigma-machine-using-ruby)
|
15
|
-
helped me understand some aspects of the internal workings of the Enigma and
|
13
|
+
Many thanks to Kevin Sylvestre, whose
|
14
|
+
[blog post](https://ksylvest.com/posts/2015-01-03/the-enigma-machine-using-ruby)
|
15
|
+
helped me understand some aspects of the internal workings of the Enigma and
|
16
16
|
how the signals flowed through the pieces of the machine.
|
17
17
|
|
18
18
|
## Installation
|
@@ -33,89 +33,89 @@ Or install it yourself as:
|
|
33
33
|
|
34
34
|
## Architecture
|
35
35
|
|
36
|
-
The [`RotorMachine::Machine`](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Machine)
|
36
|
+
The [`RotorMachine::Machine`](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Machine)
|
37
37
|
class serves as the entrypoint and orchestrator for an Enigma machine.
|
38
|
-
|
38
|
+
|
39
39
|
### Components of an Enigma machine
|
40
|
-
|
41
|
-
The Enigma machine, as represented by the [RotorMachine](http://www.rubydoc.info/github/tammycravit/rotor_machine/master)
|
40
|
+
|
41
|
+
The Enigma machine, as represented by the [RotorMachine](http://www.rubydoc.info/github/tammycravit/rotor_machine/master)
|
42
42
|
module, consists of the following components:
|
43
|
-
|
44
|
-
* One or more [rotors](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Rotor), which
|
45
|
-
perform the transposition ciphering and also rotate to produce a polyalphabetic (rather
|
43
|
+
|
44
|
+
* One or more [rotors](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Rotor), which
|
45
|
+
perform the transposition ciphering and also rotate to produce a polyalphabetic (rather
|
46
46
|
than simple substitution) cipher.
|
47
|
-
|
48
|
-
* A [reflector](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Reflector), which
|
47
|
+
|
48
|
+
* A [reflector](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Reflector), which
|
49
49
|
performs a simple symmetric substitution of letters
|
50
|
-
|
51
|
-
* A [plugboard](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Plugboard), which
|
50
|
+
|
51
|
+
* A [plugboard](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Plugboard), which
|
52
52
|
allows pairs of letters to be transposed on a per-message basis.
|
53
|
-
|
54
|
-
On an actual Enigma machine, these components are all electromechanical, and
|
55
|
-
the Enigma also included a keyboard, a grid of lights to show the results, and
|
56
|
-
in some cases a printer. Since this is a simulated Enigma, obviously, no
|
53
|
+
|
54
|
+
On an actual Enigma machine, these components are all electromechanical, and
|
55
|
+
the Enigma also included a keyboard, a grid of lights to show the results, and
|
56
|
+
in some cases a printer. Since this is a simulated Enigma, obviously, no
|
57
57
|
keyboard/printer are supplied here. In this simulation, the
|
58
58
|
[Machine](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/RotorMachine/Machine)
|
59
59
|
class serves to encapsulate all of these components.
|
60
|
-
|
60
|
+
|
61
61
|
The polyalphabetic encryption of the Enigma comes from the fact that the
|
62
62
|
rotors are linked (mechanically in a real Enigma) so that they rotate
|
63
63
|
one or more "steps" after each character, changing the signal paths and
|
64
64
|
transpositions. This means that a sequence of the same plaintext character
|
65
65
|
will encipher to different ciphertext characters.
|
66
|
-
|
66
|
+
|
67
67
|
The rotors are designed to advance such that each time a rotor completes
|
68
68
|
a full revolution, it will advance the rotor to its left once. The rotors
|
69
69
|
allow you to configure how many positions they advance when they do. So,
|
70
70
|
assuming all rotors are advancing one position at a time, if the rotors
|
71
71
|
have position "AAZ", their state after the next character is typed will
|
72
72
|
be "ABA".
|
73
|
-
|
73
|
+
|
74
74
|
To learn much more about the inner workings of actual Enigma machines,
|
75
75
|
visit [Enigma Machine (Wikipedia)](https://en.wikipedia.org/wiki/Enigma_machine).
|
76
|
-
|
76
|
+
|
77
77
|
### The Signal Path of Letters
|
78
|
-
|
78
|
+
|
79
79
|
Here's a visual depiction of the signal path of a single character through
|
80
80
|
a (physical) Enigma machine:
|
81
81
|
|
82
82
|

|
83
83
|
|
84
|
-
As you can see, the electrical signal from a keypress is routed through the
|
85
|
-
plugboard, then through each of the rotors in sequence from left to right.
|
86
|
-
The signal then passes through the reflector (where it is transposed again),
|
87
|
-
then back through the rotors in reverse order, and finally back through the
|
88
|
-
plugboard a second time before being displayed on the light grid and/or
|
84
|
+
As you can see, the electrical signal from a keypress is routed through the
|
85
|
+
plugboard, then through each of the rotors in sequence from left to right.
|
86
|
+
The signal then passes through the reflector (where it is transposed again),
|
87
|
+
then back through the rotors in reverse order, and finally back through the
|
88
|
+
plugboard a second time before being displayed on the light grid and/or
|
89
89
|
printer.
|
90
|
-
|
90
|
+
|
91
91
|
The result of the machine's signal path being a loop is that encryption and
|
92
92
|
decryption are the same operation. That is to say, if you set the rotors
|
93
93
|
and plugboard, and then type your plaintext into the machine, you'll get
|
94
94
|
a string of ciphertext. If you then reset the machine to its initial state
|
95
95
|
and type the ciphertext characters into the machine, you'll produce your
|
96
96
|
original plaintext.
|
97
|
-
|
98
|
-
One consequence of the Enigma's design is that a plaintext letter will never
|
99
|
-
encipher to itself. The Allies were able to exploit this property to help
|
100
|
-
[break the Enigma's encryption](https://en.wikipedia.org/wiki/Cryptanalysis_of_the_Enigma)
|
97
|
+
|
98
|
+
One consequence of the Enigma's design is that a plaintext letter will never
|
99
|
+
encipher to itself. The Allies were able to exploit this property to help
|
100
|
+
[break the Enigma's encryption](https://en.wikipedia.org/wiki/Cryptanalysis_of_the_Enigma)
|
101
101
|
during World War II.
|
102
|
-
|
102
|
+
|
103
103
|
## Usage
|
104
104
|
|
105
105
|
To use the RotorMachine Enigma machine, you need to perform the following
|
106
106
|
steps:
|
107
|
-
|
107
|
+
|
108
108
|
1. Create a new `RotorMachine::Machine` object.
|
109
109
|
2. Add one or more `RotorMachine::Rotor`s to the `rotors` array.
|
110
110
|
3. Set the `reflector` to an instance of the `RotorMachine::Reflector` class.
|
111
111
|
4. Make any desired connections in the Plugboard.
|
112
112
|
5. Optionally, set the rotor positions with `#set_rotors`.
|
113
|
-
|
113
|
+
|
114
114
|
You're now ready to encipher and decipher your text using the `#encipher`
|
115
115
|
method to encode/decode, and `#set_rotors` to reset the machine state.
|
116
|
-
|
116
|
+
|
117
117
|
The `#default_machine` and `#empty_machine` class methods are shortcut
|
118
|
-
factory methods whcih set up, respectively, a fully configured machine
|
118
|
+
factory methods whcih set up, respectively, a fully configured machine
|
119
119
|
with a default set of rotors and reflector, and an empty machine with
|
120
120
|
no rotors or reflector.
|
121
121
|
|
@@ -134,7 +134,7 @@ machine.rotors << RotorMachine::Rotor.new(RotorMachine::Rotor::ROTOR_II, "A", 1)
|
|
134
134
|
machine.rotors << RotorMachine::Rotor.new(RotorMachine::Rotor::ROTOR_III, "A", 1)
|
135
135
|
machine.reflector = RotorMachine::Reflector.new(RotorMachine::Reflector::REFLECTOR_A)
|
136
136
|
|
137
|
-
machine.plugboard.connect("A", "M")
|
137
|
+
machine.plugboard.connect("A", "M")
|
138
138
|
machine.plugboard.connect("Q", "K")
|
139
139
|
|
140
140
|
machine.set_rotors("CFL")
|
@@ -145,7 +145,7 @@ machine.set_rotors("CFL")
|
|
145
145
|
new_plaintext = machine.encipher(ciphertext) # => "THISI SASUP ERSEC RETME SSAGE"
|
146
146
|
```
|
147
147
|
|
148
|
-
## Example - Simplified Setup Using the Factory
|
148
|
+
## Example - Simplified Setup Using the Factory
|
149
149
|
|
150
150
|
```ruby
|
151
151
|
require 'rotor_machine'
|
@@ -164,58 +164,83 @@ machine.set_rotors("CFL")
|
|
164
164
|
new_plaintext = machine.encipher(ciphertext) # => "THISI SASUP ERSEC RETME SSAGE"
|
165
165
|
```
|
166
166
|
|
167
|
+
## Using the Wrapper DSL
|
168
|
+
|
169
|
+
A simple wrapper DSL (domain-specific language) is provided, primarily for
|
170
|
+
testing and other "conversational" or interactive uses. This DSL is defined in
|
171
|
+
the `RotorMachine::Session` class. Usage is similar to the following:
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
RotorMachine.Session do
|
175
|
+
default_machine
|
176
|
+
|
177
|
+
set_rotors "AAA"
|
178
|
+
connect "A", "G"
|
179
|
+
encipher "THIS IS A SUPER SECRET MESSAGE"
|
180
|
+
ct = last_result
|
181
|
+
|
182
|
+
set_rotors "AAA"
|
183
|
+
encipher ct
|
184
|
+
puts last_result # THISI SASUP ERSEC RETME SSAGE
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
After the operations in the block are executed, the `RotorMachine.Session` method
|
189
|
+
will return the `RotorMachine::Session` object, which can be further reused if
|
190
|
+
needed.
|
191
|
+
|
167
192
|
## Documentation
|
168
193
|
|
169
|
-
The classes in
|
170
|
-
[`lib/rotor_machine/`](https://github.com/tammycravit/rotor_machine/tree/master/lib/rotor_machine)
|
171
|
-
all contain [documentation](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/) that
|
172
|
-
pretty exhaustively describe their operation.
|
173
|
-
The RSpec tests in the [`spec/`](https://github.com/tammycravit/rotor_machine/tree/master/spec)
|
194
|
+
The classes in
|
195
|
+
[`lib/rotor_machine/`](https://github.com/tammycravit/rotor_machine/tree/master/lib/rotor_machine)
|
196
|
+
all contain [documentation](http://www.rubydoc.info/github/tammycravit/rotor_machine/master/) that
|
197
|
+
pretty exhaustively describe their operation.
|
198
|
+
The RSpec tests in the [`spec/`](https://github.com/tammycravit/rotor_machine/tree/master/spec)
|
174
199
|
directory are also instructive for how the library works and how to use it.
|
175
200
|
|
176
201
|
## Development
|
177
202
|
|
178
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
179
|
-
run `rake spec` to run the tests. You can also run `bin/console` for an
|
203
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
204
|
+
run `rake spec` to run the tests. You can also run `bin/console` for an
|
180
205
|
interactive prompt that will allow you to experiment.
|
181
206
|
|
182
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
207
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
183
208
|
|
184
|
-
To release a new version, update the version number in `version.rb`, and then
|
185
|
-
run `bundle exec rake release`, which will create a git tag for the version,
|
209
|
+
To release a new version, update the version number in `version.rb`, and then
|
210
|
+
run `bundle exec rake release`, which will create a git tag for the version,
|
186
211
|
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
187
212
|
|
188
|
-
This gem depends on the [`tcravit_ruby_lib`](https://github.com/tammycravit/tcravit_ruby_lib)
|
189
|
-
gem, which provides Rake tasks to update the version number. You can use the
|
190
|
-
`bundle exec rake version:bump:build`, `bundle exec version:bump:minor` and
|
191
|
-
`bundle exec rake version:bump:major` tasks to increment the parts of
|
213
|
+
This gem depends on the [`tcravit_ruby_lib`](https://github.com/tammycravit/tcravit_ruby_lib)
|
214
|
+
gem, which provides Rake tasks to update the version number. You can use the
|
215
|
+
`bundle exec rake version:bump:build`, `bundle exec version:bump:minor` and
|
216
|
+
`bundle exec rake version:bump:major` tasks to increment the parts of
|
192
217
|
the version number. (These tasks rewrite the file
|
193
|
-
[`lib/rotor_machine/version.rb`](https://github.com/tammycravit/rotor_machine/blob/master/lib/rotor_machine/version.rb).
|
194
|
-
After using them, you'll need to run a `git add lib/rotor_machine/version.rb`
|
218
|
+
[`lib/rotor_machine/version.rb`](https://github.com/tammycravit/rotor_machine/blob/master/lib/rotor_machine/version.rb).
|
219
|
+
After using them, you'll need to run a `git add lib/rotor_machine/version.rb`
|
195
220
|
and `git commit -m "version bump"`.
|
196
221
|
|
197
222
|
### Contributing
|
198
223
|
|
199
|
-
Bug reports and pull requests are welcome on GitHub at
|
200
|
-
[https://github.com/tammycravit/rotor_machine]. Pull requests for code changes
|
224
|
+
Bug reports and pull requests are welcome on GitHub at
|
225
|
+
[https://github.com/tammycravit/rotor_machine]. Pull requests for code changes
|
201
226
|
should include [RSpec](http://rspec.info) tests for the new/changed features.
|
202
227
|
Pull requests for documentation and other updates are also welcome.
|
203
228
|
|
204
|
-
This project is intended to be a safe, welcoming space for collaboration, and
|
205
|
-
contributors are expected to adhere to the
|
229
|
+
This project is intended to be a safe, welcoming space for collaboration, and
|
230
|
+
contributors are expected to adhere to the
|
206
231
|
[Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
207
|
-
Contributions from people who identify as women, BIPOC folx, LGBT folx,
|
232
|
+
Contributions from people who identify as women, BIPOC folx, LGBT folx,
|
208
233
|
and members of other marginalized communities are especially welcomed.
|
209
234
|
|
210
235
|
### Code of Conduct
|
211
236
|
|
212
|
-
Everyone interacting in the RotorMachine project’s codebases, issue trackers,
|
213
|
-
chat rooms and mailing lists is expected to follow the
|
237
|
+
Everyone interacting in the RotorMachine project’s codebases, issue trackers,
|
238
|
+
chat rooms and mailing lists is expected to follow the
|
214
239
|
[code of conduct](https://github.com/tammycravit/rotor_machine/blob/master/CODE_OF_CONDUCT.md).
|
215
240
|
|
216
241
|
## License
|
217
242
|
|
218
|
-
The gem is available as open source under the terms of the
|
243
|
+
The gem is available as open source under the terms of the
|
219
244
|
[Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) license.
|
220
245
|
|
221
246
|
## Image Credits
|
@@ -223,6 +248,6 @@ The gem is available as open source under the terms of the
|
|
223
248
|
* Enigma image - from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Bundesarchiv_Bild_183-2007-0705-502,_Chiffriermaschine_%22Enigma%22.jpg),
|
224
249
|
provided by Das Bundesarchiv (German Federal Archives).
|
225
250
|
|
226
|
-
* Enigma signal path image - from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Enigma_wiring_kleur.svg),
|
251
|
+
* Enigma signal path image - from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Enigma_wiring_kleur.svg),
|
227
252
|
by [MesserWoland](https://commons.wikimedia.org/wiki/User:MesserWoland)
|
228
253
|
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module RotorMachine
|
2
|
+
##
|
3
|
+
# The {Session} object provides a very simple DSL for "conversational" interactions
|
4
|
+
# with the {RotorMachine::Machine} and its subordinate classes. This is useful for
|
5
|
+
# interactive and experimental applications, for testing, and so forth.
|
6
|
+
#
|
7
|
+
# Eventually, a {Pry}-based REPL loop might be added to the project, but this
|
8
|
+
# functionality does not exist yet.
|
9
|
+
#
|
10
|
+
# Instance methods are a loose wrapper around the rest of the library and are only
|
11
|
+
# loosely documented here. Argument validation is handled by simply bubbling up
|
12
|
+
# exceptions raised by the implementatation method.
|
13
|
+
#
|
14
|
+
# == Example Usage
|
15
|
+
#
|
16
|
+
# RotorMachine.Session do
|
17
|
+
# default_machine
|
18
|
+
#
|
19
|
+
# set_rotors "AAA"
|
20
|
+
# connect "A", "G"
|
21
|
+
# encipher "THIS IS A SUPER SECRET MESSAGE"
|
22
|
+
# ct = last_result
|
23
|
+
#
|
24
|
+
# set_rotors "AAA"
|
25
|
+
# encipher ct
|
26
|
+
# puts last_result # THISI SASUP ERSEC RETME SSAGE
|
27
|
+
# end
|
28
|
+
class Session
|
29
|
+
##
|
30
|
+
# Initialize the {RotorMachine::Session} instance. The methods of this object,
|
31
|
+
# except for {#machine} and {#last_result}, are primarily intended to be
|
32
|
+
# called within the {Session} block (via {instance_eval}).
|
33
|
+
#
|
34
|
+
# @param opts [Hash] The setup options hash. Currently unused, but any options
|
35
|
+
# provided are stored.
|
36
|
+
# @param block [Block] The operations block. If provided, it is executed via
|
37
|
+
# {instance_eval}. The instance is returned following
|
38
|
+
# execution of the block.
|
39
|
+
def initialize(opts={}, &block)
|
40
|
+
@opts = opts
|
41
|
+
@machine = RotorMachine::Factory.empty_machine()
|
42
|
+
@last_result = nil
|
43
|
+
instance_eval(&block) if block_given?
|
44
|
+
return self
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Create a rotor and add it to the machine.
|
49
|
+
def rotor(kind, position=0, step_size=1)
|
50
|
+
r = RotorMachine::Factory.build_rotor rotor_kind: kind,
|
51
|
+
initial_position: position,
|
52
|
+
step_size: step_size
|
53
|
+
@machine.rotors << r if r.is_a?(RotorMachine::Rotor)
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Set the machine's reflector.
|
58
|
+
def reflector(kind, position="A")
|
59
|
+
r = RotorMachine::Factory.build_reflector reflector_kind: kind,
|
60
|
+
initial_position: position
|
61
|
+
@machine.reflector = r if r.is_a?(RotorMachine::Reflector)
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Connect a pair of letters on the machine's plugboard.
|
66
|
+
def connect(from, to)
|
67
|
+
@machine.plugboard.connect(from, to)
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Disconnect a letter (and its inverse) from the machine's plugboard.
|
72
|
+
def disconnect(from)
|
73
|
+
@machine.plugboard.disconnect(from)
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Encipher a string.
|
78
|
+
def encipher(the_string="")
|
79
|
+
res = @machine.encipher(the_string)
|
80
|
+
@last_result = res
|
81
|
+
res
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
#Set the positions of the rotors.
|
86
|
+
def set_positions(pos_string)
|
87
|
+
@machine.set_rotors(pos_string)
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Remove all rotors from the machine.
|
92
|
+
def clear_rotors
|
93
|
+
@machine.rotors = []
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Remove all connections from the plugboard.
|
98
|
+
def clear_plugboard
|
99
|
+
@machine.plugboard = RotorMachine::Plugboard.new
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Configure the machine to its default state (as in the {RotorMachine::Factory}
|
104
|
+
# object's {default_machine} method.)
|
105
|
+
def default_machine
|
106
|
+
@machine = RotorMachine::Factory.default_machine
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Configure the machine to its empty state (as in the {RotorMachine::Factory}
|
111
|
+
# object's {empty_machine} method.)
|
112
|
+
def empty_machine
|
113
|
+
@machine = RotorMachine::Factory.empty_machine
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Return the inner {RotorMachine::Machine} object.
|
118
|
+
def machine
|
119
|
+
@machine
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Return the results of the last {encipher} operation, or nil.
|
124
|
+
def last_result
|
125
|
+
@last_result
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# {plug} is a convenience alias for {connect}
|
130
|
+
alias_method "plug", "connect"
|
131
|
+
|
132
|
+
##
|
133
|
+
# {unplug} is a convenience alias for {disconnect}
|
134
|
+
alias_method "unplug", "disconnect"
|
135
|
+
|
136
|
+
##
|
137
|
+
# {set_rotors} is a convenience alias for {set_positions}
|
138
|
+
alias_method "set_rotors", "set_positions"
|
139
|
+
|
140
|
+
##
|
141
|
+
# {encode} is a convenience alias for {encipher}
|
142
|
+
alias_method "encode", "encipher"
|
143
|
+
|
144
|
+
##
|
145
|
+
# {cipher} is a convenience alias for {encipher}
|
146
|
+
alias_method "cipher", "encipher"
|
147
|
+
|
148
|
+
##
|
149
|
+
# {the_machine} is a convenience alias for {machine}
|
150
|
+
alias_method "the_machine", "machine"
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# The class method Session is the entrypoint for the DSL. When invoked with a
|
155
|
+
# block, it creates a new {RotorMachine::Session} object, passes the block to
|
156
|
+
# it to be run with {instance_eval}, and then the {RotorMachine::Session} object
|
157
|
+
# is returned to the caller.
|
158
|
+
def self.Session(opts={}, &block)
|
159
|
+
RotorMachine::Session.new(opts, &block)
|
160
|
+
end
|
161
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rotor_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tammy Cravit
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tcravit_ruby_lib
|
@@ -195,6 +195,7 @@ files:
|
|
195
195
|
- lib/rotor_machine/plugboard.rb
|
196
196
|
- lib/rotor_machine/reflector.rb
|
197
197
|
- lib/rotor_machine/rotor.rb
|
198
|
+
- lib/rotor_machine/session.rb
|
198
199
|
- lib/rotor_machine/string_extensions.rb
|
199
200
|
- lib/rotor_machine/version.rb
|
200
201
|
- rotor_machine.gemspec
|