morse_me_nicely 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0e242e84aa15495dc60ee404d8a4226fdaf7bbc2
4
+ data.tar.gz: 18fa718bd9455bbc6f9de8005449ded79de0a7b6
5
+ SHA512:
6
+ metadata.gz: 3ffae5107884ed71c3d426baab6f9ff2fab652b4f0caf47115da386a33e38f5b443cc9def71e19d9067b5d3fb7fefbf3b428f7d0fb6ada01176736ae50ee40d9
7
+ data.tar.gz: dbf89c966f8eb7274df1b00b9e0391fcdcee873c2420cd14344d51735b5669d9b81ee822b64784656f0d569c4774c946ac84321813f8edd596e0be047eb1571d
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rspec', '3.6.0'
4
+ gem 'rake', '12.0.0'
5
+ gem 'thor', '0.19.4'
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.3)
5
+ rake (12.0.0)
6
+ rspec (3.6.0)
7
+ rspec-core (~> 3.6.0)
8
+ rspec-expectations (~> 3.6.0)
9
+ rspec-mocks (~> 3.6.0)
10
+ rspec-core (3.6.0)
11
+ rspec-support (~> 3.6.0)
12
+ rspec-expectations (3.6.0)
13
+ diff-lcs (>= 1.2.0, < 2.0)
14
+ rspec-support (~> 3.6.0)
15
+ rspec-mocks (3.6.0)
16
+ diff-lcs (>= 1.2.0, < 2.0)
17
+ rspec-support (~> 3.6.0)
18
+ rspec-support (3.6.0)
19
+ thor (0.19.4)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ rake (= 12.0.0)
26
+ rspec (= 3.6.0)
27
+ thor (= 0.19.4)
28
+
29
+ BUNDLED WITH
30
+ 1.14.3
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ begin
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = "-f doc"
6
+ end
7
+
8
+ task :default => :spec
9
+ rescue LoadError
10
+ raise "No Rspec available"
11
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Exit cleanly from an early interrupt
4
+ Signal.trap("INT") { exit 1 }
5
+
6
+ require_relative '../lib/morse_me_nicely'
7
+
8
+ MorseMeNicely::CLI.start(ARGV)
@@ -0,0 +1,42 @@
1
+ characters:
2
+ "a": ".-"
3
+ "b": "-..."
4
+ "c": "-.-."
5
+ "d": "-.."
6
+ "e": "."
7
+ "f": "..-."
8
+ "g": "--."
9
+ "h": "...."
10
+ "i": ".."
11
+ "j": ".---"
12
+ "k": "-.-"
13
+ "l": ".-.."
14
+ "m": "--"
15
+ "n": "-."
16
+ "o": "---"
17
+ "p": ".--."
18
+ "q": "--.-"
19
+ "r": ".-."
20
+ "s": "..."
21
+ "t": "-"
22
+ "u": "..-"
23
+ "v": "...-"
24
+ "w": ".--"
25
+ "x": "-..-"
26
+ "y": "-.--"
27
+ "z": "--.."
28
+ "0": "-----"
29
+ "1": ".----"
30
+ "2": "..---"
31
+ "3": "...--"
32
+ "4": "....-"
33
+ "5": "....."
34
+ "6": "-...."
35
+ "7": "--..."
36
+ "8": "---.."
37
+ "9": "----."
38
+ ".": ".-.-.-"
39
+ ",": "--..--"
40
+ separators:
41
+ character: '|'
42
+ word: '/'
@@ -0,0 +1,26 @@
1
+ require 'yaml'
2
+ require 'thor'
3
+
4
+ MORSE_ME_NICELY_PATH = File.dirname(__FILE__) + "/morse_me_nicely/"
5
+
6
+ [
7
+ "encoder",
8
+ "obfuscator",
9
+ "cli"
10
+ ].each do |utility|
11
+ require MORSE_ME_NICELY_PATH + utility
12
+ end
13
+
14
+ module MorseMeNicely
15
+ class InvalidInputError < StandardError; end
16
+
17
+ class Processor
18
+
19
+ def self.encode(input_text, without_obfuscation=false)
20
+ text = Encoder.new(input_text).encoded_input
21
+ text = Obfuscator.new(text).obfuscated_input unless without_obfuscation
22
+ text
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module MorseMeNicely
2
+
3
+ class CLI < Thor
4
+
5
+ desc "encode [--without-obfuscation] [--input-file=path/to/input_file] [--output-file=path/to/output_file]", "Encode message using obfuscated morse code"
6
+ method_options :without_obfuscation => :boolean
7
+ method_options :input_file => :string
8
+ method_options :output_file => :string
9
+
10
+ def encode
11
+ if options[:input_file]
12
+ input_text = File.read(options[:input_file])
13
+ else
14
+ input_text = ask(set_color("Write the message:", Thor::Shell::Color::GREEN))
15
+ end
16
+ encoded_text = MorseMeNicely::Processor::encode(input_text, options[:without_obfuscation])
17
+ if options[:output_file]
18
+ output_file = File.new(options[:output_file], "w+")
19
+ output_file << encoded_text
20
+ output_file.close
21
+ say("Encoded message has been saved to selected file.", Thor::Shell::Color::GREEN)
22
+ else
23
+ say("Encoded message:", Thor::Shell::Color::GREEN)
24
+ say(encoded_text)
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,51 @@
1
+ module MorseMeNicely
2
+
3
+ class Encoder
4
+
5
+ ENCODING_REFERENCE_PATH = MORSE_ME_NICELY_PATH + "../../data/morse_reference.yml"
6
+
7
+ def initialize(input_text)
8
+ @input_text = input_text
9
+ @encoding_reference = YAML::load_file(ENCODING_REFERENCE_PATH)
10
+ end
11
+
12
+ def encoded_input
13
+ validate_input_text
14
+ @input_text.split(/\n/).map do |line|
15
+ line.scan(/\w+\.?\,?/).map do |word|
16
+ translate_word(word)
17
+ end.join(@encoding_reference["separators"]["word"])
18
+ end.join("\n")
19
+ end
20
+
21
+ private
22
+
23
+ def validate_input_text
24
+ raise InvalidInputError, "No text input found" unless @input_text.is_a?(String)
25
+ invalid_characters = get_input_invalid_characters
26
+ unless invalid_characters.empty?
27
+ raise InvalidInputError, "Input text contains invalid characters: #{invalid_characters.join(" ")}"
28
+ end
29
+ end
30
+
31
+ def get_input_invalid_characters
32
+ input_copy = @input_text.downcase.dup
33
+ @encoding_reference["characters"].keys.each do |character|
34
+ input_copy.gsub!(character, '')
35
+ end
36
+ input_copy.gsub(/\s+/, '').split('').uniq
37
+ end
38
+
39
+ def translate_word(word)
40
+ word.split('').map do |character|
41
+ translate_character(character)
42
+ end.join(@encoding_reference["separators"]["character"])
43
+ end
44
+
45
+ def translate_character(character)
46
+ @encoding_reference["characters"][character.downcase]
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,68 @@
1
+ module MorseMeNicely
2
+
3
+ class Obfuscator
4
+
5
+ def initialize(input_text)
6
+ @input_text = input_text
7
+ end
8
+
9
+ def obfuscated_input
10
+ process_dashes(
11
+ process_dots(
12
+ @input_text
13
+ )
14
+ )
15
+ end
16
+
17
+ private
18
+
19
+ def process_dots(text)
20
+ text_copy = text.dup
21
+ get_ordered_unique_consecutive_chars(text, :dot).each do |uniq_consecutive_dots|
22
+ text_copy.gsub!(uniq_consecutive_dots, encode_consecutive_dots(uniq_consecutive_dots))
23
+ end
24
+ text_copy
25
+ end
26
+
27
+ def process_dashes(text)
28
+ text_copy = text.dup
29
+ get_ordered_unique_consecutive_chars(text, :dash).each do |uniq_consecutive_dashes|
30
+ text_copy.gsub!(uniq_consecutive_dashes, encode_consecutuve_dashes(uniq_consecutive_dashes))
31
+ end
32
+ text_copy
33
+ end
34
+
35
+ def get_ordered_unique_consecutive_chars(text, character)
36
+ regex = case character
37
+ when :dot
38
+ /\.+/
39
+ when :dash
40
+ /\-+/
41
+ end
42
+ text.scan(regex).uniq.sort do |v1, v2|
43
+ v2.length <=> v1.length
44
+ end
45
+ end
46
+
47
+ def encode_consecutive_dots(dots)
48
+ length = dots.length
49
+ if length > 9
50
+ raise InvalidInputError, "Number of consecutive dots can't be greater than 9"
51
+ else
52
+ length.to_s
53
+ end
54
+ end
55
+
56
+ def encode_consecutuve_dashes(dashes)
57
+ ascii_idx_addition = ("A".ord - 1)
58
+ ascii_nr = dashes.length + ascii_idx_addition
59
+ if ascii_nr > "Z".ord
60
+ raise InvalidInputError, "Number of consecutive dashes can't be greater than the size of alphabet"
61
+ else
62
+ ascii_nr.chr
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,100 @@
1
+ require_relative '../spec_helper'
2
+
3
+ RSpec.describe MorseMeNicely::Encoder, "#encoded_input" do
4
+
5
+ context "when input text is not valid" do
6
+
7
+ context "when input is not a string" do
8
+
9
+ subject do
10
+ described_class.new(true)
11
+ end
12
+
13
+ it "raises InvalidInput error" do
14
+ expect { subject.encoded_input }.to raise_error(MorseMeNicely::InvalidInputError, "No text input found")
15
+ end
16
+
17
+ end
18
+
19
+ context "when input text contains ambiguous characters" do
20
+
21
+ subject do
22
+ described_class.new("I'm to stupid; 2 > 1")
23
+ end
24
+
25
+ it "raises InvalidInput error with invalid characters listed" do
26
+ expect { subject.encoded_input }.to raise_error(MorseMeNicely::InvalidInputError, "Input text contains invalid characters: ' ; >")
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ context "when input text is valid" do
34
+
35
+ context "translation of characters" do
36
+
37
+ subject do
38
+ described_class.new("l")
39
+ end
40
+
41
+ it "returns correct translation based on provided reference" do
42
+ expect(subject.encoded_input).to eq ".-.."
43
+ end
44
+
45
+ end
46
+
47
+ context "characters separation" do
48
+
49
+ subject do
50
+ described_class.new("l2")
51
+ end
52
+
53
+ it "returns translated characters separated by pipe '|'" do
54
+ expect(subject.encoded_input).to eq ".-..|..---"
55
+ end
56
+
57
+ end
58
+
59
+ context "words separation" do
60
+
61
+ it "separates with forward slash '/'" do
62
+ encoder = described_class.new("jm 13")
63
+ expect(encoder.encoded_input).to eq ".---|--/.----|...--"
64
+ end
65
+
66
+ it "considers coma and full stop as part of the preceding word" do
67
+ encoder = described_class.new("you, me and he.")
68
+ expect(encoder.encoded_input).to eq "-.--|---|..-|--..--/--|./.-|-.|-../....|.|.-.-.-"
69
+ end
70
+
71
+ end
72
+
73
+ context "case sensitivity" do
74
+
75
+ it "does ignore character case" do
76
+ encoder_downcase = described_class.new("dominik")
77
+ encoder_uppercase = described_class.new("DOMINIK")
78
+ expect(encoder_downcase.encoded_input).to eq encoder_uppercase.encoded_input
79
+ end
80
+
81
+ end
82
+
83
+ context "whitespaces" do
84
+
85
+ it "considers multiple spaces as one" do
86
+ encoder_single_space = described_class.new("foo bar")
87
+ encoder_multiple_spaces = described_class.new("foo bar")
88
+ expect(encoder_single_space.encoded_input).to eq encoder_multiple_spaces.encoded_input
89
+ end
90
+
91
+ it "respects new line characters" do
92
+ encoder = described_class.new("a\nbc\nbc cd")
93
+ expect(encoder.encoded_input).to eq ".-\n-...|-.-.\n-...|-.-./-.-.|-.."
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,76 @@
1
+ require_relative '../spec_helper'
2
+
3
+ RSpec.describe MorseMeNicely::Obfuscator, "#obfuscated_input" do
4
+
5
+ context "when input text is invalid" do
6
+
7
+ context "when number of consecutive dots is greater than 9" do
8
+
9
+ subject do
10
+ described_class.new("...........")
11
+ end
12
+
13
+ it "raises InvalidInput error" do
14
+ expect { subject.obfuscated_input }.to(
15
+ raise_error(MorseMeNicely::InvalidInputError,
16
+ "Number of consecutive dots can't be greater than 9")
17
+ )
18
+ end
19
+
20
+ end
21
+
22
+ context "when number of consecutive dashes is greater than size of alphabet" do
23
+
24
+ subject do
25
+ described_class.new("---------------------------")
26
+ end
27
+
28
+ it "raises InvalidInput error" do
29
+ expect { subject.obfuscated_input }.to(
30
+ raise_error(MorseMeNicely::InvalidInputError,
31
+ "Number of consecutive dashes can't be greater than the size of alphabet")
32
+ )
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ context "when input text is valid" do
40
+
41
+ context "consecutive dots" do
42
+
43
+ it "replaces number of consecutive dots with count number" do
44
+ expect(described_class.new(".").obfuscated_input).to eq "1"
45
+ expect(described_class.new("..").obfuscated_input).to eq "2"
46
+ expect(described_class.new("...").obfuscated_input).to eq "3"
47
+ expect(described_class.new("....").obfuscated_input).to eq "4"
48
+ expect(described_class.new(".....").obfuscated_input).to eq "5"
49
+ end
50
+
51
+ end
52
+
53
+ context "consecutive dashes" do
54
+
55
+ it "replaces number of consecutive dashes with the uppercase letter of alphabet at that position" do
56
+ expect(described_class.new("-").obfuscated_input).to eq "A"
57
+ expect(described_class.new("--").obfuscated_input).to eq "B"
58
+ expect(described_class.new("---").obfuscated_input).to eq "C"
59
+ expect(described_class.new("----").obfuscated_input).to eq "D"
60
+ expect(described_class.new("-----").obfuscated_input).to eq "E"
61
+ end
62
+
63
+ end
64
+
65
+ context "misc" do
66
+
67
+ it "replaces number of consecutive dots and dashes in text block based on rules above" do
68
+ obfuscator = described_class.new("../.-|--/..|-./-|.-.|---|..-|-...|.-..|.")
69
+ expect(obfuscator.obfuscated_input).to eq "2/1A|B/2|A1/A|1A1|C|2A|A3|1A2|1"
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1 @@
1
+ require_relative '../lib/morse_me_nicely'
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morse_me_nicely
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dominik Sito
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '12.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.0'
55
+ description: A simple gem to encode and obfuscate text input using morse code
56
+ email: dominik.sito@gmail.com
57
+ executables:
58
+ - morse_me_nicely
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - Gemfile
63
+ - Gemfile.lock
64
+ - Rakefile
65
+ - bin/morse_me_nicely
66
+ - data/morse_reference.yml
67
+ - lib/morse_me_nicely.rb
68
+ - lib/morse_me_nicely/cli.rb
69
+ - lib/morse_me_nicely/encoder.rb
70
+ - lib/morse_me_nicely/obfuscator.rb
71
+ - spec/morse_me_nicely/encoder_spec.rb
72
+ - spec/morse_me_nicely/obfuscator_spec.rb
73
+ - spec/spec_helper.rb
74
+ homepage: https://github.com/railis/morse_me_nicely
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.5.2
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Morse Me Nicely!
98
+ test_files:
99
+ - spec/morse_me_nicely/encoder_spec.rb
100
+ - spec/morse_me_nicely/obfuscator_spec.rb
101
+ - spec/spec_helper.rb