enigma_ruby 0.1.2
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 +7 -0
- data/README.md +43 -0
- data/lib/enigma_ruby/commands/advance_rotors_command.rb +17 -0
- data/lib/enigma_ruby/commands/command.rb +7 -0
- data/lib/enigma_ruby/commands/encode_rotor_backward_command.rb +13 -0
- data/lib/enigma_ruby/commands/encode_rotor_forward_command.rb +13 -0
- data/lib/enigma_ruby/commands/reflect_command.rb +7 -0
- data/lib/enigma_ruby/commands/swap_plugboard_command.rb +7 -0
- data/lib/enigma_ruby/enigma.rb +37 -0
- data/lib/enigma_ruby/plugboard.rb +14 -0
- data/lib/enigma_ruby/reflector.rb +10 -0
- data/lib/enigma_ruby/rotor.rb +26 -0
- data/lib/enigma_ruby/version.rb +3 -0
- data/lib/enigma_ruby.rb +23 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 12988cada24f1d22f2954abae0f25f952454cb870c3886683f72f32a5fce40c9
|
4
|
+
data.tar.gz: dcdb04c44fb455aa150932d2ae9dc4f48f1464f958bc2fb216853fc103a1136a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a9c385e78a24de6d8704702b6e4d55fb2620de00316ec35e29ed9cc6d5bbf2c567c270effafbba69b8d3fd210cbca57cfc8260093a6d92d9929f0fdd3151668
|
7
|
+
data.tar.gz: 29c215ce716dddb4bfabb17a7f437e98df70f1d8db94a56111de720b54aa2e4dd1bfd153b37012c3ef003801bb6f9518d0d60e8216b9d55b4ec17b32dd109066
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
## EnigmaRuby
|
2
|
+
|
3
|
+
[](https://github.com/chibicco/enigma_ruby/actions/workflows/minitest.yml)
|
4
|
+
|
5
|
+
EnigmaRuby faithfully recreates the functionality of the historical Enigma machine in Ruby.
|
6
|
+
This gem allows you to encrypt and decrypt messages using customizable rotors, reflectors, and plugboards, offering a hands-on experience with classic cryptographic techniques.
|
7
|
+
|
8
|
+
### Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'enigma_ruby'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
```shell
|
19
|
+
$ bundle install
|
20
|
+
```
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
```shell
|
25
|
+
$ gem install enigma_ruby
|
26
|
+
```
|
27
|
+
|
28
|
+
### Usage
|
29
|
+
|
30
|
+
```rub
|
31
|
+
require 'enigma_ruby'
|
32
|
+
|
33
|
+
EnigmaRuby.encrypt('HELLO WORLD')
|
34
|
+
```
|
35
|
+
|
36
|
+
### References
|
37
|
+
|
38
|
+
- [Enigma Machine - Wikipedia](https://en.wikipedia.org/wiki/Enigma_machine)
|
39
|
+
- [The_Imitation_Game](https://en.wikipedia.org/wiki/The_Imitation_Game)
|
40
|
+
|
41
|
+
### License
|
42
|
+
|
43
|
+
The gem is available as open source under the terms of the MIT License.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module EnigmaRuby
|
2
|
+
class AdvanceRotorsCommand < Command
|
3
|
+
def initialize(rotors)
|
4
|
+
@rotors = rotors
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(_)
|
8
|
+
@rotors[0].advance
|
9
|
+
@rotors.each_with_index do |rotor, i|
|
10
|
+
next if i == 0
|
11
|
+
break unless @rotors[i - 1].at_notch?
|
12
|
+
|
13
|
+
rotor.advance
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module EnigmaRuby
|
2
|
+
class EncodeRotorBackwardCommand < Command
|
3
|
+
def initialize(rotors)
|
4
|
+
@rotors = rotors
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(context)
|
8
|
+
@rotors.reverse_each do |rotor|
|
9
|
+
context[:encoded_char] = rotor.encode_backward(context[:encoded_char])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module EnigmaRuby
|
2
|
+
class EncodeRotorForwardCommand < Command
|
3
|
+
def initialize(rotors)
|
4
|
+
@rotors = rotors
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(context)
|
8
|
+
@rotors.each do |rotor|
|
9
|
+
context[:encoded_char] = rotor.encode_forward(context[:encoded_char])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module EnigmaRuby
|
2
|
+
SKIP_CHARACTERS_REGEX = /[']/.freeze
|
3
|
+
NON_ENCRYPTED_CHARACTERS_REGEX = /[ .,;0-9]/.freeze
|
4
|
+
|
5
|
+
class Enigma
|
6
|
+
def initialize(rotor_settings = [])
|
7
|
+
initialize_rotors(rotor_settings)
|
8
|
+
@commands = [
|
9
|
+
SwapPlugboardCommand.new,
|
10
|
+
EncodeRotorForwardCommand.new(@rotors),
|
11
|
+
ReflectCommand.new,
|
12
|
+
EncodeRotorBackwardCommand.new(@rotors),
|
13
|
+
SwapPlugboardCommand.new,
|
14
|
+
AdvanceRotorsCommand.new(@rotors)
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def encrypt(cleartext)
|
19
|
+
encoded_text = ''
|
20
|
+
cleartext.each_char do |char|
|
21
|
+
next if SKIP_CHARACTERS_REGEX .match?(char)
|
22
|
+
next encoded_text << char if NON_ENCRYPTED_CHARACTERS_REGEX .match?(char)
|
23
|
+
|
24
|
+
context = { encoded_char: char }
|
25
|
+
@commands.each { |command| command.execute(context) }
|
26
|
+
encoded_text << context[:encoded_char]
|
27
|
+
end
|
28
|
+
encoded_text
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def initialize_rotors(rotor_settings)
|
34
|
+
@rotors = rotor_settings.map { |config| Rotor.new(config[:wiring], config[:position]) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module EnigmaRuby
|
2
|
+
class Rotor
|
3
|
+
def initialize(wiring, position = 0)
|
4
|
+
@wiring = wiring.chars
|
5
|
+
@position = @notch = position
|
6
|
+
end
|
7
|
+
|
8
|
+
def encode_forward(char)
|
9
|
+
index = (char.ord - 'A'.ord + @position) % 26
|
10
|
+
@wiring[index]
|
11
|
+
end
|
12
|
+
|
13
|
+
def encode_backward(char)
|
14
|
+
index = @wiring.index(char)
|
15
|
+
((index - @position) % 26 + 'A'.ord).chr
|
16
|
+
end
|
17
|
+
|
18
|
+
def advance
|
19
|
+
@position = (@position + 1) % 26
|
20
|
+
end
|
21
|
+
|
22
|
+
def at_notch?
|
23
|
+
@position == @notch
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/enigma_ruby.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "enigma_ruby/version"
|
2
|
+
require "enigma_ruby/rotor"
|
3
|
+
require "enigma_ruby/reflector"
|
4
|
+
require "enigma_ruby/plugboard"
|
5
|
+
require "enigma_ruby/enigma"
|
6
|
+
require "enigma_ruby/commands/command"
|
7
|
+
require "enigma_ruby/commands/advance_rotors_command"
|
8
|
+
require "enigma_ruby/commands/encode_rotor_backward_command"
|
9
|
+
require "enigma_ruby/commands/encode_rotor_forward_command"
|
10
|
+
require "enigma_ruby/commands/reflect_command"
|
11
|
+
require "enigma_ruby/commands/swap_plugboard_command"
|
12
|
+
|
13
|
+
module EnigmaRuby
|
14
|
+
DEFAULT_ROTOR_SETTINGS = [
|
15
|
+
{ wiring: 'EKMFLGDQVZNTOWYHXUSPAIBRCJ', position: 12 },
|
16
|
+
{ wiring: 'AJDKSIRUXBLHWTMCQGZNPYFVOE', position: 2 },
|
17
|
+
{ wiring: 'BDFHJLCPRTXVZNYEIWGAKMUSQO', position: 10 },
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
def self.encrypt(cleartext, rotor_settings = DEFAULT_ROTOR_SETTINGS)
|
21
|
+
Enigma.new(rotor_settings).encrypt(cleartext)
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: enigma_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- chibicco
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-07-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
description: This gem allows you to simulate the encryption process of the Enigma
|
56
|
+
machine.
|
57
|
+
email:
|
58
|
+
- me@chibicco.dev
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- README.md
|
64
|
+
- lib/enigma_ruby.rb
|
65
|
+
- lib/enigma_ruby/commands/advance_rotors_command.rb
|
66
|
+
- lib/enigma_ruby/commands/command.rb
|
67
|
+
- lib/enigma_ruby/commands/encode_rotor_backward_command.rb
|
68
|
+
- lib/enigma_ruby/commands/encode_rotor_forward_command.rb
|
69
|
+
- lib/enigma_ruby/commands/reflect_command.rb
|
70
|
+
- lib/enigma_ruby/commands/swap_plugboard_command.rb
|
71
|
+
- lib/enigma_ruby/enigma.rb
|
72
|
+
- lib/enigma_ruby/plugboard.rb
|
73
|
+
- lib/enigma_ruby/reflector.rb
|
74
|
+
- lib/enigma_ruby/rotor.rb
|
75
|
+
- lib/enigma_ruby/version.rb
|
76
|
+
homepage: https://github.com/chibicco/enigma_ruby/
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubygems_version: 3.5.15
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: A Ruby implementation of the Enigma machine
|
99
|
+
test_files: []
|