enigma_encrypto 0.1.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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +49 -0
  6. data/Rakefile +2 -0
  7. data/bin/crack +5 -0
  8. data/bin/decrypt +5 -0
  9. data/bin/encrypt +5 -0
  10. data/encrypted.txt +1 -0
  11. data/enigma_encrypto.gemspec +22 -0
  12. data/lib/enigma_encrypto/crack.rb +80 -0
  13. data/lib/enigma_encrypto/cracker.rb +52 -0
  14. data/lib/enigma_encrypto/dateoffset_gen.rb +29 -0
  15. data/lib/enigma_encrypto/decrypt.rb +70 -0
  16. data/lib/enigma_encrypto/encrypt.rb +68 -0
  17. data/lib/enigma_encrypto/encrypted.txt +1 -0
  18. data/lib/enigma_encrypto/file_handler.rb +49 -0
  19. data/lib/enigma_encrypto/key_gen.rb +36 -0
  20. data/lib/enigma_encrypto/lib_helper.rb +6 -0
  21. data/lib/enigma_encrypto/rotation_num_gen.rb +40 -0
  22. data/lib/enigma_encrypto/rotator.rb +24 -0
  23. data/lib/enigma_encrypto/serialize.rb +70 -0
  24. data/lib/enigma_encrypto/testfile.txt +1 -0
  25. data/lib/enigma_encrypto/testfile2.txt +1 -0
  26. data/lib/enigma_encrypto/version.rb +3 -0
  27. data/lib/enigma_encrypto.rb +19 -0
  28. data/spec/coverage/.last_run.json +5 -0
  29. data/spec/coverage/.resultset.json +7 -0
  30. data/spec/coverage/.resultset.json.lock +0 -0
  31. data/spec/crack_spec.rb +74 -0
  32. data/spec/cracker_spec.rb +49 -0
  33. data/spec/dateoffset_gen_spec.rb +40 -0
  34. data/spec/decrypt_spec.rb +63 -0
  35. data/spec/decrypted.txt +0 -0
  36. data/spec/empty.txt +0 -0
  37. data/spec/encrypt_spec.rb +70 -0
  38. data/spec/encrypted.txt +1 -0
  39. data/spec/file_handler_spec.rb +60 -0
  40. data/spec/key_gen_spec.rb +53 -0
  41. data/spec/rotation_num_gen_spec.rb +55 -0
  42. data/spec/rotator_spec.rb +63 -0
  43. data/spec/spec_helper.rb +11 -0
  44. data/spec/testfile.txt +1 -0
  45. data/spec/testfile2.txt +0 -0
  46. metadata +138 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ef6d7fe8e4e928fc39caf8e1a3ab79eddb8463da
4
+ data.tar.gz: 01dd02c1e5e57fe79fad94549624ea7b52cb994e
5
+ SHA512:
6
+ metadata.gz: 3ea58560a4881da1207fb24c34b592fe08b8456db307d220c4176b6f9688ce2d890d73bce3b43af98b6cf38f58c20d52d4bce5b6dd9771d3356cd4020af72078
7
+ data.tar.gz: 8edf0919b8869b6d25498c524d04632b0f9ebdf8dd46852a757812336498b35ceefb74c116b7a8019583084d455334da6a59d262fa5aae8bd8163238a2215004
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in enigma_encrypto.gemspec
4
+ gemspec
5
+ gem "coveralls", require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Ebowe Blessing
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # EnigmaEncrypto
2
+
3
+ This is my first checkpoint project done under the Andela Institute curriculum titled ENIGMA.
4
+
5
+ ENIGMA entails creation of an Ecryptor gem like the Ceasar cipher.
6
+ Contains encrypt ruby file that when called with two file names as command line arguments, it encrypts the first file and saves in the other.
7
+ Also contains decrypt ruby file that when called with two file names, date of creation and a key as command line arguments, it encrypts the first file and saves in the other.
8
+ Also includes a little twist where you can actually crack an encrypted file without a key.
9
+
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'enigma_encrypto'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install enigma_encrypto
26
+
27
+ ## Usage
28
+
29
+ To use add the directory of the bin folder of this gem to your Systems Path/Environment variables.
30
+ You can then call `encrypt`, `decrypt` or `crack`, on the file you want to work on, and also with a destination file name.
31
+ File to be encrypted, decrypted or cracked must be in your working directory.
32
+
33
+ Example: To call encrypt on a message.txt file in my desktop folder
34
+
35
+ $ cd desktop
36
+ $ encrypt message.txt encrypted.txt
37
+ =>#Created encrypted.txt with the key 12345 and date 300815
38
+
39
+ You can also write the absolute path of the file if you dont want to change working directory.
40
+
41
+ $ encrypt desktop/message.txt encrypted.txt
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it ( https://github.com/[andela-bebowe]/enigma_gem/fork )
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/crack ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "enigma_encrypto"
4
+
5
+ EnigmaEncrypto.crack
data/bin/decrypt ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "enigma_encrypto"
4
+
5
+ EnigmaEncrypto.decrypt
data/bin/encrypt ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "enigma_encrypto"
4
+
5
+ EnigmaEncrypto.encrypt
data/encrypted.txt ADDED
@@ -0,0 +1 @@
1
+ umbtyqfx2uj16yn5 2r9b6vaf oyycos
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'enigma_encrypto/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "enigma_encrypto"
8
+ spec.version = EnigmaEncrypto::VERSION
9
+ spec.authors = ["Ebowe Blessing"]
10
+ spec.email = ["blessing.ebowe@andela.com"]
11
+ spec.summary = %q{Encryper, Decrypter and Cracker when you forget your key}
12
+ spec.description = "See Readme doc."
13
+ spec.license = "MIT"
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = ["encrypt", "decrypt", "crack"]
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.7"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.required_ruby_version = ">= 2.1"
22
+ end
@@ -0,0 +1,80 @@
1
+ require_relative "lib_helper"
2
+
3
+ module EnigmaEncrypto
4
+
5
+ class Crack
6
+
7
+ def initialize
8
+ @file_handler = FileHandler.new
9
+ @rotator = Rotator.new
10
+ @rotation_num_gen = RotationNumGen.new
11
+ end
12
+
13
+ def get_command_args
14
+ if ARGV.length != 3
15
+ puts "Oooops!\nIncorrect number of arguments supplied.\nTry again."
16
+ false
17
+ else
18
+ @encrypted = ARGV[0]
19
+ @cracked = ARGV[1]
20
+ @date = ARGV[2]
21
+ end
22
+ end
23
+
24
+ def check_command_args
25
+ if ("%06d" % (@date.to_i)).size != 6 || @date.to_i <= 0
26
+ puts "Incorrect date entered"
27
+ return false
28
+ end
29
+ operation = @file_handler.check_file_useability(@encrypted, @cracked)
30
+ return false if operation == false || operation == "c"
31
+ File.truncate(@cracked, 0) if operation == "w"
32
+ true
33
+ end
34
+
35
+ def get_crack_key
36
+ @opened_encrypted = @file_handler.read(@encrypted)
37
+ @length = @opened_encrypted.size
38
+ @offset = DateOffsetGen.new.get_decrypter_offset(@date)
39
+ @key = Cracker.new(@opened_encrypted, @length, @offset).get_key
40
+ end
41
+
42
+ def crack
43
+ @reverse_array = @rotation_num_gen.crack_num_arr(@key, @offset)
44
+ @opened_encrypted.rewind
45
+ crack_encrypted
46
+ @opened_encrypted.close
47
+ end
48
+
49
+ def action
50
+ exit if !get_command_args
51
+ exit if !check_command_args
52
+ get_crack_key
53
+ crack
54
+ @key.map!{|digit| "%d" % digit }
55
+ @key = Serialize.new(@key).action
56
+ puts "Cracked #{@encrypted} and created #{@cracked} with key #{@key} and date #{@date}."
57
+ true
58
+ end
59
+
60
+ private
61
+
62
+ def crack_encrypted
63
+ reverse_array_index = 0
64
+ while @length > 0
65
+ character_in_encry = @opened_encrypted.getc
66
+ reverse_encrypted(character_in_encry, reverse_array_index)
67
+ reverse_array_index += 1
68
+ reverse_array_index = 0 if reverse_array_index == 4
69
+ @length -= 1
70
+ end
71
+ end
72
+
73
+ def reverse_encrypted(character, index)
74
+ cracked_char = @rotator.reverse_text(character, @reverse_array[index])
75
+ @file_handler.writer(@cracked, cracked_char)
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "rotation_num_gen"
2
+ require_relative "rotator"
3
+
4
+ module EnigmaEncrypto
5
+
6
+ class Cracker
7
+
8
+ def initialize(file, length, offset)
9
+ @offset = offset
10
+ @file = file
11
+ @length = length
12
+ @character_map = Rotator.new.character_map_creation
13
+ end
14
+
15
+ def locate_position_to_start_crack
16
+ seek_pt = @length % 4
17
+ @file.seek(@length - (4 + seek_pt))
18
+ @end_index = 3 - seek_pt
19
+ end
20
+
21
+ def needed_four_of_file
22
+ @text_arr = []
23
+ 4.times do
24
+ @text_arr << @file.getc
25
+ end
26
+ @text_arr.map!{|letter| @character_map.index(letter)}
27
+ end
28
+
29
+ def the_end_arr
30
+ @end_arr = [".", ".", "e", "n", "d", ".", "."]
31
+ @end_arr.map!{|letter| @character_map.index(letter)}
32
+ end
33
+
34
+ def creating_key
35
+ key_arr = []
36
+ 4.times do |index|
37
+ key_arr << @text_arr[index] - @offset[index] - @end_arr[@end_index]
38
+ @end_index += 1
39
+ end
40
+ key_arr
41
+ end
42
+
43
+ def get_key
44
+ locate_position_to_start_crack
45
+ needed_four_of_file
46
+ the_end_arr
47
+ creating_key
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,29 @@
1
+ module EnigmaEncrypto
2
+
3
+ class DateOffsetGen
4
+
5
+ attr_accessor :todays_date
6
+
7
+ def initialize
8
+ @todays_date = Time.now.strftime("%02d%02m%02y")
9
+ end
10
+
11
+ def get_offset
12
+ date_squared_last_four
13
+ end
14
+
15
+ def get_decrypter_offset(date)
16
+ @todays_date = date
17
+ date_squared_last_four
18
+ end
19
+
20
+ private
21
+
22
+ def date_squared_last_four
23
+ (@todays_date.to_i**2).to_s.split("").slice(-4..-1).map do |num|
24
+ num.to_i
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,70 @@
1
+ require_relative "lib_helper"
2
+
3
+ module EnigmaEncrypto
4
+
5
+ class Decrypt
6
+
7
+ def initialize
8
+ @file_handler = FileHandler.new
9
+ @rotator = Rotator.new
10
+ @rotation_num_gen = RotationNumGen.new
11
+ end
12
+
13
+ def get_command_args
14
+ if ARGV.length != 4
15
+ puts "Oooops!\nIncorrect number of arguments supplied.\nTry again."
16
+ return false
17
+ else
18
+ @encrypted = ARGV[0]
19
+ @decrypted = ARGV[1]
20
+ @key = ARGV[2]
21
+ @date = ARGV[3]
22
+ end
23
+ end
24
+
25
+ def check_command_args
26
+ if ("%05d" % (@key.to_i)).size != 5 || ("%06d" % (@date.to_i)).size != 6
27
+ puts "Incorrect key or date entered"
28
+ return false; end
29
+ operation = @file_handler.check_file_useability(@encrypted, @decrypted)
30
+ return false if operation == false || operation == "c"
31
+ File.truncate(@decrypted, 0) if operation == "w"
32
+ true
33
+ end
34
+
35
+ def decrypt
36
+ @reverse_array = @rotation_num_gen.reverse_num_array(@key, @date)
37
+ @opened_msg = @file_handler.read(@encrypted)
38
+ length = @opened_msg.size
39
+ decrypt_message(length)
40
+ @opened_msg.close
41
+ end
42
+
43
+ def action
44
+ exit if !get_command_args
45
+ exit if !check_command_args
46
+ decrypt
47
+ puts "Decrypted #{@decrypted} with the key #{@key} and date #{@date}"
48
+ end
49
+
50
+ private
51
+
52
+ def decrypt_message(length)
53
+ reverse_num_index = 0
54
+ while length > 0
55
+ character_in_msg = @opened_msg.getc
56
+ reverse_msg(character_in_msg, reverse_num_index)
57
+ reverse_num_index += 1
58
+ reverse_num_index = 0 if reverse_num_index == 4
59
+ length -= 1
60
+ end
61
+ end
62
+
63
+ def reverse_msg(character, index)
64
+ reversed_char = @rotator.reverse_text(character, @reverse_array[index])
65
+ @file_handler.writer(@decrypted, reversed_char)
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,68 @@
1
+ require_relative "lib_helper"
2
+
3
+ module EnigmaEncrypto
4
+
5
+ class Encrypt
6
+
7
+ def initialize
8
+ @file_handler = FileHandler.new
9
+ @rotator = Rotator.new
10
+ @rotation_num_gen = RotationNumGen.new
11
+ end
12
+
13
+ def get_command_args
14
+ if ARGV.length != 2
15
+ puts "Oooops!\nIncorrect number of arguments supplied.\nTry again."
16
+ false
17
+ else
18
+ @message = ARGV[0]
19
+ @encrypted = ARGV[1]
20
+ end
21
+ end
22
+
23
+ def check_command_args
24
+ operation = @file_handler.check_file_useability(@message, @encrypted)
25
+ return false if operation == false || operation == "c"
26
+ File.truncate(@encrypted, 0) if operation == "w"
27
+ true
28
+ end
29
+
30
+ def encrypt
31
+ @opened_msg = @file_handler.read(@message)
32
+ length = @opened_msg.size
33
+ encrypt_message(length)
34
+ @opened_msg.close
35
+ end
36
+
37
+ def action
38
+ exit if !get_command_args
39
+ exit if !check_command_args
40
+ encrypt
41
+ key = @rotation_num_gen.showkey
42
+ date = @rotation_num_gen.today_date
43
+ puts "Created #{@encrypted} with the key #{key} and date #{date}"
44
+ true
45
+ end
46
+
47
+ private
48
+
49
+ def encrypt_message(length)
50
+ rotation_num_index = 0
51
+ while length > 0
52
+ character_in_msg = @opened_msg.getc
53
+ rotate_msg(character_in_msg, rotation_num_index)
54
+ rotation_num_index += 1
55
+ rotation_num_index = 0 if rotation_num_index == 4
56
+ length -= 1
57
+ end
58
+ end
59
+
60
+ def rotate_msg(character, index)
61
+ @rotation = @rotation_num_gen.rotation_num_array
62
+ rotated_char = @rotator.rotate_text(character, @rotation[index])
63
+ @file_handler.writer(@encrypted, rotated_char)
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1 @@
1
+ cq90gua4kye8o2i,s6mdw qh0b5vg2 va
@@ -0,0 +1,49 @@
1
+ module EnigmaEncrypto
2
+
3
+ class FileHandler
4
+
5
+ #file1 represents file to be read from
6
+ #file2 represents file to be written to
7
+
8
+ def messages
9
+ @msg1 = "File to be read doesnt exist or is empty.\nTry again with an existing file"
10
+ @msg2 = "File to be written to already exists!"
11
+ @msg3 = "To cancel operation, Press 'C'\nTo overwrite File, Type 'W'"
12
+ @msg4 = "Incorrect Entry"
13
+ end
14
+
15
+ def check_file_useability(file1, file2)
16
+ messages
17
+ if (!(File.exists?file1) || (File.zero? file1))
18
+ puts @msg1
19
+ return false
20
+ end
21
+ if File.exists?file2
22
+ puts @msg2 + "\n" + @msg3
23
+ operation_collector
24
+ end
25
+ end
26
+
27
+ def read(msg)
28
+ readable = File.open(msg, "r")
29
+ end
30
+
31
+ def writer(msg, word)
32
+ writable = File.open(msg, "a")
33
+ writable.write(word)
34
+ writable.close
35
+ end
36
+
37
+ private
38
+
39
+ def operation_collector
40
+ operation = ($stdin.gets.chomp).downcase
41
+ if operation != "w" && operation != "c"
42
+ puts @msg4
43
+ operation = false
44
+ end
45
+ return operation
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,36 @@
1
+ module EnigmaEncrypto
2
+
3
+ class KeyGen
4
+
5
+ attr_accessor :rand_num
6
+
7
+ def initialize
8
+ rand = Random.new
9
+ @rand_num = rand(10000..99999).to_s.split("")
10
+ end
11
+
12
+ def initial_rotation_keys
13
+ generate_keys
14
+ end
15
+
16
+ def display_key
17
+ (@rand_num.map{|num| num.to_i}).join
18
+ end
19
+
20
+ def initial_decryption_keys(key)
21
+ @rand_num = key
22
+ generate_keys
23
+ end
24
+
25
+ private
26
+
27
+ def generate_keys
28
+ key_values = []
29
+ 4.times do |index|
30
+ key_values << ((@rand_num[index] + @rand_num[index + 1])).to_i
31
+ end
32
+ key_values
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ require_relative "cracker"
2
+ require_relative "dateoffset_gen"
3
+ require_relative "file_handler"
4
+ require_relative "rotator"
5
+ require_relative "rotation_num_gen"
6
+ require_relative "serialize"
@@ -0,0 +1,40 @@
1
+ require_relative "dateoffset_gen"
2
+ require_relative "key_gen"
3
+
4
+ module EnigmaEncrypto
5
+
6
+ class RotationNumGen
7
+
8
+ attr_accessor :key, :offset, :showkey, :today_date
9
+
10
+ def initialize
11
+ @key_without_offset = KeyGen.new
12
+ @key = @key_without_offset.initial_rotation_keys
13
+ @showkey = @key_without_offset.display_key
14
+ @offsetgen = DateOffsetGen.new
15
+ @offset = @offsetgen.get_offset
16
+ @today_date = @offsetgen.todays_date
17
+ end
18
+
19
+ def rotation_num_array
20
+ rotation_num = []
21
+ 4.times do |index|
22
+ rotation_num << @key[index] + @offset[index]
23
+ end
24
+ rotation_num
25
+ end
26
+
27
+ def reverse_num_array(key, date)
28
+ @offset = @offsetgen.get_decrypter_offset(date)
29
+ @key = @key_without_offset.initial_decryption_keys(key)
30
+ rotation_num_array
31
+ end
32
+
33
+ def crack_num_arr(key, date)
34
+ @key = key
35
+ @offset = date
36
+ rotation_num_array
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ module EnigmaEncrypto
2
+
3
+ class Rotator
4
+ def character_map_creation
5
+ @character_map = []
6
+ @character_map.concat(("a".."z").to_a)
7
+ @character_map.concat(("0".."9").to_a)
8
+ @character_map.concat([" ", ".", ","])
9
+ end
10
+ def rotator(rotation)
11
+ character_map_creation
12
+ rotated_character_map = @character_map.rotate(rotation)
13
+ Hash[@character_map.zip(rotated_character_map)]
14
+ end
15
+ def rotate_text(text, rotation)
16
+ rotation_for_text = rotator(rotation)
17
+ rotation_for_text[text]
18
+ end
19
+ def reverse_text(text, reversion)
20
+ reversion = 0 - reversion
21
+ rotate_text(text, reversion)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ module EnigmaEncrypto
2
+
3
+ class Serialize
4
+
5
+ def initialize(key)
6
+ @key = key
7
+ end
8
+
9
+ def make_all_keys_positive
10
+ @key.map! do |num|
11
+ num = num.to_i
12
+ while num < 0 do
13
+ num += 39
14
+ end
15
+ "%02d" % num
16
+ end
17
+ end
18
+
19
+ def create_original_key_array
20
+ @new_key_array = []
21
+ 3.times do |index|
22
+ key_for_next_index = key_getter(@key[index], @key[index + 1])
23
+ @key[index + 1] = key_for_next_index
24
+ end
25
+ @new_key_array << @key[3]
26
+ end
27
+
28
+ def make_new_key_string
29
+ new_key_string = ""
30
+ new_key_string << @new_key_array[0][0]
31
+ new_key_string << @new_key_array[1][0]
32
+ new_key_string << @new_key_array[1][1]
33
+ new_key_string << @new_key_array[3][0]
34
+ new_key_string << @new_key_array[3][1]
35
+ end
36
+
37
+ def action
38
+ make_all_keys_positive
39
+ create_original_key_array
40
+ make_new_key_string
41
+ end
42
+
43
+ private
44
+
45
+ def key_getter(key0, key1)
46
+ @key1 = key1
47
+ @count = 0
48
+ if key0[1] == key1[0]
49
+ @new_key_array << key0
50
+ return key1; end
51
+ while key0[1] != key1[0] do
52
+ key1 = (key1.to_i + 39).to_s
53
+ if key0[1] == key1[0]
54
+ @new_key_array << key0
55
+ return key1
56
+ elsif key1.to_i > 99
57
+ key1 = (@key1.to_i - 39).to_s
58
+ @count += 1
59
+ end
60
+ if @count == 1
61
+ key0 = (key0.to_i + 39).to_s
62
+ @count = 0
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1 @@
1
+ abcdefghijklmnopqrstuvwxyz..end..