enigma_machine 0.0.1.alpha1 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +38 -0
- data/lib/enigma_machine/rotor.rb +16 -11
- data/lib/enigma_machine/version.rb +1 -1
- data/lib/enigma_machine.rb +4 -3
- data/spec/enigma_machine_spec.rb +80 -2
- data/spec/integration_spec.rb +58 -1
- data/spec/rotor_spec.rb +71 -1
- metadata +14 -10
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# EnigmaMachine
|
2
|
+
|
3
|
+
This is a simulator for an [Enigma Machine](http://en.wikipedia.org/wiki/Enigma_machine). It currently simulates both the Enigma I/M3 and the Enigma M4. It also allows for specifying your own custom rotor/reflector configurations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'enigma_machine'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install enigma_machine
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
e = EnigmaMachine.new(
|
22
|
+
:reflector => :B,
|
23
|
+
:rotors => [[:i, 10], [:ii, 14], [:iii, 21]],
|
24
|
+
:plug_pairs => %w(AP BR CM FZ GJ IL NT OV QS WX)
|
25
|
+
)
|
26
|
+
e.set_rotors('V', 'Q', 'Q')
|
27
|
+
|
28
|
+
result = e.translate('HABHV HLYDF NADZY')
|
29
|
+
|
30
|
+
See `integration_spec.rb` for some more examples
|
31
|
+
|
32
|
+
## Contributing
|
33
|
+
|
34
|
+
1. Fork it
|
35
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
36
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
37
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
38
|
+
5. Create new Pull Request
|
data/lib/enigma_machine/rotor.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
class EnigmaMachine
|
2
2
|
class Rotor
|
3
3
|
STANDARD_ROTORS = {
|
4
|
-
:i => "
|
5
|
-
:ii => "
|
6
|
-
:iii => "
|
7
|
-
:iv => "
|
8
|
-
:v => "
|
9
|
-
:vi => "
|
10
|
-
:vii => "
|
11
|
-
:viii => "
|
12
|
-
:beta => "
|
13
|
-
:gamma => "
|
4
|
+
:i => "EKMFLGDQVZNTOWYHXUSPAIBRCJ_Q",
|
5
|
+
:ii => "AJDKSIRUXBLHWTMCQGZNPYFVOE_E",
|
6
|
+
:iii => "BDFHJLCPRTXVZNYEIWGAKMUSQO_V",
|
7
|
+
:iv => "ESOVPZJAYQUIRHXLNFTGKDCMWB_J",
|
8
|
+
:v => "VZBRGITYUPSDNHLXAWMJQOFECK_Z",
|
9
|
+
:vi => "JPGVOUMFYQBENHZRDKASXLICTW_MZ",
|
10
|
+
:vii => "NZJHGRCXMYSWBOUFAIVLPEKQDT_MZ",
|
11
|
+
:viii => "FKQHTLXOCBJSPDZRAMEWNIUYGV_MZ",
|
12
|
+
:beta => "LEYJVCNIXWPBQMDRTAKZGFUHOS_", # The beta and gamma rotors caould only go
|
13
|
+
:gamma => "FSOKANUERHMBTIYCWLQPZXVGJD_", # in position 4, and hence have no notches.
|
14
14
|
}
|
15
15
|
|
16
16
|
def initialize(rotor_spec, ring_setting, decorated)
|
@@ -18,8 +18,9 @@ class EnigmaMachine
|
|
18
18
|
raise ConfigurationError unless STANDARD_ROTORS.has_key?(rotor_spec)
|
19
19
|
rotor_spec = STANDARD_ROTORS[rotor_spec]
|
20
20
|
end
|
21
|
-
mapping,
|
21
|
+
mapping, notch_positions = rotor_spec.split('_', 2)
|
22
22
|
@mapping = mapping.each_char.map {|c| ALPHABET.index(c) }
|
23
|
+
@notch_positions = notch_positions.split('')
|
23
24
|
@ring_offset = ring_setting - 1
|
24
25
|
@decorated = decorated
|
25
26
|
self.position = 'A'
|
@@ -36,6 +37,10 @@ class EnigmaMachine
|
|
36
37
|
@position = (@position + 1).modulo(26)
|
37
38
|
end
|
38
39
|
|
40
|
+
def at_notch?
|
41
|
+
@notch_positions.include?(self.position)
|
42
|
+
end
|
43
|
+
|
39
44
|
def forward(letter)
|
40
45
|
index = add_offset ALPHABET.index(letter)
|
41
46
|
new_index = sub_offset @mapping[index]
|
data/lib/enigma_machine.rb
CHANGED
@@ -28,8 +28,8 @@ class EnigmaMachine
|
|
28
28
|
case letter
|
29
29
|
when /[A-Z]/
|
30
30
|
press_key(letter)
|
31
|
-
when
|
32
|
-
|
31
|
+
when /[ -]/
|
32
|
+
letter
|
33
33
|
end
|
34
34
|
end.join
|
35
35
|
end
|
@@ -37,7 +37,8 @@ class EnigmaMachine
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def advance_rotors
|
40
|
-
|
40
|
+
@rotors[-3].advance_position if @rotors[-2].at_notch?
|
41
|
+
@rotors[-2].advance_position if @rotors[-2].at_notch? or @rotors[-1].at_notch?
|
41
42
|
@rotors[-1].advance_position
|
42
43
|
end
|
43
44
|
end
|
data/spec/enigma_machine_spec.rb
CHANGED
@@ -63,10 +63,11 @@ describe EnigmaMachine do
|
|
63
63
|
@e.translate('ABC').should == 'BCD'
|
64
64
|
end
|
65
65
|
|
66
|
-
it "should pass through spaces unmodified" do
|
66
|
+
it "should pass through spaces and dashes unmodified" do
|
67
67
|
@e.should_not_receive(:press_key).with(' ')
|
68
|
+
@e.should_not_receive(:press_key).with('-')
|
68
69
|
|
69
|
-
@e.translate('
|
70
|
+
@e.translate('ABCDE F----').should == 'ZZZZZ Z----'
|
70
71
|
end
|
71
72
|
|
72
73
|
it "should upcase the input before passing to press_key" do
|
@@ -109,6 +110,83 @@ describe EnigmaMachine do
|
|
109
110
|
end
|
110
111
|
|
111
112
|
describe "advancing rotors" do
|
113
|
+
before :each do
|
114
|
+
@left_rotor = mock("Rotor", :at_notch? => false, :advance_position => nil)
|
115
|
+
@middle_rotor = mock("Rotor", :at_notch? => false, :advance_position => nil)
|
116
|
+
@right_rotor = mock("Rotor", :at_notch? => false, :advance_position => nil)
|
117
|
+
EnigmaMachine::Rotor.stub!(:new).with(:i, anything(), anything()).and_return(@left_rotor)
|
118
|
+
EnigmaMachine::Rotor.stub!(:new).with(:ii, anything(), anything()).and_return(@middle_rotor)
|
119
|
+
EnigmaMachine::Rotor.stub!(:new).with(:iii, anything(), anything()).and_return(@right_rotor)
|
120
|
+
EnigmaMachine::Reflector.stub!(:new)
|
121
|
+
EnigmaMachine::Plugboard.stub!(:new)
|
122
|
+
|
123
|
+
@e = EnigmaMachine.new(:rotors => [[:i,1], [:ii,2], [:iii,3]])
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "right rotor" do
|
127
|
+
it "should be advanced every time" do
|
128
|
+
@right_rotor.should_receive(:advance_position)
|
129
|
+
@e.send(:advance_rotors)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "middle rotor" do
|
134
|
+
it "should be advanced if the right rotor is at a notch" do
|
135
|
+
@right_rotor.stub!(:at_notch?).and_return(true)
|
136
|
+
@middle_rotor.should_receive(:advance_position)
|
137
|
+
|
138
|
+
@e.send(:advance_rotors)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should be advanced if it is at a notch" do
|
142
|
+
@middle_rotor.stub!(:at_notch?).and_return(true)
|
143
|
+
@middle_rotor.should_receive(:advance_position)
|
112
144
|
|
145
|
+
@e.send(:advance_rotors)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should not be advanced otherwise" do
|
149
|
+
@middle_rotor.should_not_receive(:advance_position)
|
150
|
+
|
151
|
+
@e.send(:advance_rotors)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "left rotor" do
|
156
|
+
it "should be advanced if the middle rotor is at a notch" do
|
157
|
+
@middle_rotor.stub!(:at_notch?).and_return(true)
|
158
|
+
@left_rotor.should_receive(:advance_position)
|
159
|
+
|
160
|
+
@e.send(:advance_rotors)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should not be advanced if it is at a notch" do
|
164
|
+
@left_rotor.stub!(:at_notch?).and_return(true)
|
165
|
+
@left_rotor.should_not_receive(:advance_position)
|
166
|
+
|
167
|
+
@e.send(:advance_rotors)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should not be advanced otherwise" do
|
171
|
+
@left_rotor.should_not_receive(:advance_position)
|
172
|
+
|
173
|
+
@e.send(:advance_rotors)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "4th rotor (when present)" do
|
178
|
+
before :each do
|
179
|
+
@fourth_rotor = mock("Rotor", :at_notch? => false, :advance_position => nil)
|
180
|
+
@e.instance_variable_get('@rotors').unshift(@fourth_rotor)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should never be advanced" do
|
184
|
+
@fourth_rotor.stub!(:at_notch?).and_return(true)
|
185
|
+
@left_rotor.stub!(:at_notch?).and_return(true)
|
186
|
+
@fourth_rotor.should_not_receive(:advance_position)
|
187
|
+
|
188
|
+
@e.send(:advance_rotors)
|
189
|
+
end
|
190
|
+
end
|
113
191
|
end
|
114
192
|
end
|
data/spec/integration_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe "Integration tests" do
|
@@ -15,6 +16,46 @@ describe "Integration tests" do
|
|
15
16
|
e.translate('AEFAE JXXBN XYJTY').should == 'CONGR ATULA TIONS'
|
16
17
|
end
|
17
18
|
|
19
|
+
it "should translate a message with rotor turnover" do
|
20
|
+
e = EnigmaMachine.new(
|
21
|
+
:reflector => :B,
|
22
|
+
:rotors => [[:i, 1], [:ii, 1], [:iii, 1]]
|
23
|
+
)
|
24
|
+
e.set_rotors('A', 'B', 'R')
|
25
|
+
|
26
|
+
e.translate('MABEK GZXSG').should == 'TURNM IDDLE'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should translate a message with double stepping" do
|
30
|
+
e = EnigmaMachine.new(
|
31
|
+
:reflector => :B,
|
32
|
+
:rotors => [[:i, 1], [:ii, 1], [:iii, 1]]
|
33
|
+
)
|
34
|
+
e.set_rotors('A', 'D', 'S')
|
35
|
+
|
36
|
+
e.translate('RZFOG FYHPL').should == 'TURNS THREE'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should translate a message with ring settings" do
|
40
|
+
e = EnigmaMachine.new(
|
41
|
+
:reflector => :B,
|
42
|
+
:rotors => [[:i, 10], [:ii, 14], [:iii, 21]]
|
43
|
+
)
|
44
|
+
e.set_rotors('X', 'Y', 'Z')
|
45
|
+
|
46
|
+
e.translate('QKTPE BZIUK').should == 'GOODR ESULT'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should translate a message with a plugboard as well" do
|
50
|
+
e = EnigmaMachine.new(
|
51
|
+
:reflector => :B,
|
52
|
+
:rotors => [[:i, 10], [:ii, 14], [:iii, 21]],
|
53
|
+
:plug_pairs => %w(AP BR CM FZ GJ IL NT OV QS WX)
|
54
|
+
)
|
55
|
+
e.set_rotors('V', 'Q', 'Q')
|
56
|
+
|
57
|
+
e.translate('HABHV HLYDF NADZY').should == 'THATS ITWEL LDONE'
|
58
|
+
end
|
18
59
|
end
|
19
60
|
|
20
61
|
describe "real world sample messages" do
|
@@ -63,12 +104,28 @@ describe "Integration tests" do
|
|
63
104
|
|
64
105
|
e.set_rotors('U', 'Z', 'V')
|
65
106
|
result = e.translate('YKAE NZAP MSCH ZBFO CUVM RMDP YCOF HADZ IZME FXTH FLOL PZLF GGBO TGOX GRET DWTJ IQHL MXVJ WKZU ASTR')
|
66
|
-
result.should == '
|
107
|
+
result.should == 'STEU EREJ TANA FJOR DJAN STAN DORT QUAA ACCC VIER NEUN NEUN ZWOF AHRT ZWON ULSM XXSC HARN HORS THCO'
|
67
108
|
|
68
109
|
# German: Steuere Tanafjord an. Standort Quadrat AC4992, fahrt 20sm. Scharnhorst. [hco - padding?]
|
69
110
|
# English: Heading for Tanafjord. Position is square AC4992, speed 20 knots. Scharnhorst.
|
70
111
|
end
|
71
112
|
end
|
72
113
|
|
114
|
+
describe "Enigma M4" do
|
115
|
+
specify "U-264 (Kapitänleutnant Hartwig Looks), 1942" do
|
116
|
+
e = EnigmaMachine.new(
|
117
|
+
:reflector => :Bthin,
|
118
|
+
:rotors => [[:beta, 1], [:ii, 1], [:iv, 1], [:i, 22]],
|
119
|
+
:plug_pairs => %w(AT BL DF GJ HM NW OP QY RZ VX)
|
120
|
+
)
|
121
|
+
|
122
|
+
e.set_rotors('V', 'J', 'N', 'A')
|
123
|
+
result = e.translate('NCZW VUSX PNYM INHZ XMQX SFWX WLKJ AHSH NMCO CCAK UQPM KCSM HKSE INJU SBLK IOSX CKUB HMLL XCSJ USRR DVKO HULX WCCB GVLI YXEO AHXR HKKF VDRE WEZL XOBA FGYU JQUK GRTV UKAM EURB VEKS UHHV OYHA BCJW MAKL FKLM YFVN RIZR VVRT KOFD ANJM OLBG FFLE OPRG TFLV RHOW OPBE KVWM UQFM PWPA RMFH AGKX IIBG')
|
124
|
+
result.should == 'VONV ONJL OOKS JHFF TTTE INSE INSD REIZ WOYY QNNS NEUN INHA LTXX BEIA NGRI FFUN TERW ASSE RGED RUEC KTYW ABOS XLET ZTER GEGN ERST ANDN ULAC HTDR EINU LUHR MARQ UANT ONJO TANE UNAC HTSE YHSD REIY ZWOZ WONU LGRA DYAC HTSM YSTO SSEN ACHX EKNS VIER MBFA ELLT YNNN NNNO OOVI ERYS ICHT EINS NULL'
|
125
|
+
|
126
|
+
# German: Von Von 'Looks' F T 1132/19 Inhalt: Bei Angriff unter Wasser gedrückt, Wasserbomben. Letzter Gegnerstandort 08:30 Uhr Marine Quadrat AJ9863, 220 Grad, 8sm, stosse nach. 14mb fällt, NNO 4, Sicht 10.
|
127
|
+
# English: From Looks, radio-telegram 1132/19 contents: Forced to submerge under attack, depth charges. Last enemy location 08:30 hours, sea square AJ9863, following 220 degrees, 8 knots. [Pressure] 14 millibars falling, [wind] north-north-east 4, visibility 10.
|
128
|
+
end
|
129
|
+
end
|
73
130
|
end
|
74
131
|
end
|
data/spec/rotor_spec.rb
CHANGED
@@ -14,48 +14,70 @@ describe EnigmaMachine::Rotor do
|
|
14
14
|
r = EnigmaMachine::Rotor.new(:i, 1, :next)
|
15
15
|
r.forward('A').should == 'E'
|
16
16
|
r.forward('Q').should == 'X'
|
17
|
+
r.position = 'Q'
|
18
|
+
r.at_notch?.should == true
|
17
19
|
end
|
18
20
|
|
19
21
|
it "should support rotor ii" do
|
20
22
|
r = EnigmaMachine::Rotor.new(:ii, 1, :next)
|
21
23
|
r.forward('A').should == 'A'
|
22
24
|
r.forward('M').should == 'W'
|
25
|
+
r.position = 'E'
|
26
|
+
r.at_notch?.should == true
|
23
27
|
end
|
24
28
|
|
25
29
|
it "should support rotor iii" do
|
26
30
|
r = EnigmaMachine::Rotor.new(:iii, 1, :next)
|
27
31
|
r.forward('A').should == 'B'
|
28
32
|
r.forward('Q').should == 'I'
|
33
|
+
r.position = 'V'
|
34
|
+
r.at_notch?.should == true
|
29
35
|
end
|
30
36
|
|
31
37
|
it "should support rotor iv" do
|
32
38
|
r = EnigmaMachine::Rotor.new(:iv, 1, :next)
|
33
39
|
r.forward('A').should == 'E'
|
34
40
|
r.forward('Q').should == 'N'
|
41
|
+
r.position = 'J'
|
42
|
+
r.at_notch?.should == true
|
35
43
|
end
|
36
44
|
|
37
45
|
it "should support rotor v" do
|
38
46
|
r = EnigmaMachine::Rotor.new(:v, 1, :next)
|
39
47
|
r.forward('A').should == 'V'
|
40
48
|
r.forward('Q').should == 'A'
|
49
|
+
r.position = 'Z'
|
50
|
+
r.at_notch?.should == true
|
41
51
|
end
|
42
52
|
|
43
53
|
it "should support rotor vi" do
|
44
54
|
r = EnigmaMachine::Rotor.new(:vi, 1, :next)
|
45
55
|
r.forward('A').should == 'J'
|
46
56
|
r.forward('Q').should == 'D'
|
57
|
+
r.position = 'M'
|
58
|
+
r.at_notch?.should == true
|
59
|
+
r.position = 'Z'
|
60
|
+
r.at_notch?.should == true
|
47
61
|
end
|
48
62
|
|
49
63
|
it "should support rotor vii" do
|
50
64
|
r = EnigmaMachine::Rotor.new(:vii, 1, :next)
|
51
65
|
r.forward('A').should == 'N'
|
52
66
|
r.forward('Q').should == 'A'
|
67
|
+
r.position = 'M'
|
68
|
+
r.at_notch?.should == true
|
69
|
+
r.position = 'Z'
|
70
|
+
r.at_notch?.should == true
|
53
71
|
end
|
54
72
|
|
55
73
|
it "should support rotor viii" do
|
56
74
|
r = EnigmaMachine::Rotor.new(:viii, 1, :next)
|
57
75
|
r.forward('A').should == 'F'
|
58
76
|
r.forward('Q').should == 'A'
|
77
|
+
r.position = 'M'
|
78
|
+
r.at_notch?.should == true
|
79
|
+
r.position = 'Z'
|
80
|
+
r.at_notch?.should == true
|
59
81
|
end
|
60
82
|
|
61
83
|
it "should support rotor beta" do
|
@@ -71,9 +93,10 @@ describe EnigmaMachine::Rotor do
|
|
71
93
|
end
|
72
94
|
end
|
73
95
|
end
|
96
|
+
|
74
97
|
describe "setting and manipulating rotor positions" do
|
75
98
|
before :each do
|
76
|
-
@rotor = EnigmaMachine::Rotor.new(
|
99
|
+
@rotor = EnigmaMachine::Rotor.new(:i, 1, :foo)
|
77
100
|
end
|
78
101
|
|
79
102
|
it "should set the position to 'A' by default" do
|
@@ -99,6 +122,53 @@ describe EnigmaMachine::Rotor do
|
|
99
122
|
end
|
100
123
|
end
|
101
124
|
|
125
|
+
describe "checking notch position" do
|
126
|
+
it "should return true if the rotor is at one of the notch positions" do
|
127
|
+
rotor = EnigmaMachine::Rotor.new('EKMFLGDQVZNTOWYHXUSPAIBRCJ_DR', 1, :foo)
|
128
|
+
|
129
|
+
rotor.position = 'D'
|
130
|
+
rotor.at_notch?.should == true
|
131
|
+
|
132
|
+
rotor.position = 'R'
|
133
|
+
rotor.at_notch?.should == true
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return false otherwise" do
|
137
|
+
rotor = EnigmaMachine::Rotor.new('EKMFLGDQVZNTOWYHXUSPAIBRCJ_DR', 1, :foo)
|
138
|
+
|
139
|
+
rotor.position = 'C'
|
140
|
+
rotor.at_notch?.should == false
|
141
|
+
rotor.position = 'E'
|
142
|
+
rotor.at_notch?.should == false
|
143
|
+
|
144
|
+
rotor.position = 'Q'
|
145
|
+
rotor.at_notch?.should == false
|
146
|
+
rotor.position = 'S'
|
147
|
+
rotor.at_notch?.should == false
|
148
|
+
|
149
|
+
rotor.position = 'A'
|
150
|
+
rotor.at_notch?.should == false
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should be unaffected by the ring position" do
|
154
|
+
rotor = EnigmaMachine::Rotor.new('EKMFLGDQVZNTOWYHXUSPAIBRCJ_DR', 6, :foo)
|
155
|
+
|
156
|
+
rotor.position = 'C'
|
157
|
+
rotor.at_notch?.should == false
|
158
|
+
rotor.position = 'D'
|
159
|
+
rotor.at_notch?.should == true
|
160
|
+
rotor.position = 'E'
|
161
|
+
rotor.at_notch?.should == false
|
162
|
+
|
163
|
+
rotor.position = 'Q'
|
164
|
+
rotor.at_notch?.should == false
|
165
|
+
rotor.position = 'R'
|
166
|
+
rotor.at_notch?.should == true
|
167
|
+
rotor.position = 'S'
|
168
|
+
rotor.at_notch?.should == false
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
102
172
|
describe "forward and reverse translation" do
|
103
173
|
context "with a ring-setting of 1 (no adjustment), and a rotor position of A (the default)" do
|
104
174
|
before :each do
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enigma_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Alex Tomlins
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &18339180 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *18339180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &18357640 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *18357640
|
36
36
|
description: Enigma machine simulator
|
37
37
|
email:
|
38
38
|
- alex@tomlins.org.uk
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- .gitignore
|
44
44
|
- .rspec
|
45
45
|
- Gemfile
|
46
|
+
- README.md
|
46
47
|
- Rakefile
|
47
48
|
- enigma_machine.gemspec
|
48
49
|
- lib/enigma_machine.rb
|
@@ -70,13 +71,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
71
|
version: '0'
|
71
72
|
segments:
|
72
73
|
- 0
|
73
|
-
hash:
|
74
|
+
hash: 2207890655996414444
|
74
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
76
|
none: false
|
76
77
|
requirements:
|
77
|
-
- - ! '
|
78
|
+
- - ! '>='
|
78
79
|
- !ruby/object:Gem::Version
|
79
|
-
version:
|
80
|
+
version: '0'
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
hash: 2207890655996414444
|
80
84
|
requirements: []
|
81
85
|
rubyforge_project:
|
82
86
|
rubygems_version: 1.8.10
|