morseficator 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 701e8ad0c9dbac4e8d21a1b8147a64a6c0c69d4c1656ddabc4305473b203ea73
4
+ data.tar.gz: bc777718fb99edae238894d99c61026e953d6a7ecc671dcb53946eb6e6470736
5
+ SHA512:
6
+ metadata.gz: 1b754b1f2a0ec85ae3a1ec68f939a41f1253e3a56dce429959ec1e24110d9e8dfccbf14643c49fcdbecff48016c29ac201f7f9fcae75cd1990d4efad8986d545
7
+ data.tar.gz: 76008d058985eab5fc9e172049cd2f9227f00e6fd556e6d01bd4f41f55d82ea68651c28d5ec467ccea293366e145f423ec1f12724787b35afc1e3b867efde895
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ AllCops:
2
+ NewCops: enable
3
+
4
+ Metrics/BlockLength:
5
+ Exclude:
6
+ - spec/**/*
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in morseficator.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 12.0'
9
+ gem 'rspec', '~> 3.0'
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ morseficator (0.1.0)
5
+ bundler
6
+ clamp (~> 1.3)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ clamp (1.3.2)
12
+ diff-lcs (1.4.4)
13
+ rake (12.3.3)
14
+ rspec (3.9.0)
15
+ rspec-core (~> 3.9.0)
16
+ rspec-expectations (~> 3.9.0)
17
+ rspec-mocks (~> 3.9.0)
18
+ rspec-core (3.9.2)
19
+ rspec-support (~> 3.9.3)
20
+ rspec-expectations (3.9.2)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.9.0)
23
+ rspec-mocks (3.9.1)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.9.0)
26
+ rspec-support (3.9.3)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ morseficator!
33
+ rake (~> 12.0)
34
+ rspec (~> 3.0)
35
+
36
+ BUNDLED WITH
37
+ 2.1.4
@@ -0,0 +1,54 @@
1
+ # Morseficator
2
+
3
+ You're competing in a battle on a far away planet and you're in some trouble. You need to send a distress call to your home base for reinforcements, however, enemy agents are listening. Luckily your team have a secret encoding for messages. It's Morse code with further obfuscation.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'morseficator'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install morseficator
20
+
21
+ ## Usage
22
+
23
+ ```
24
+ Usage:
25
+ morseficator [OPTIONS] [TEXT]
26
+
27
+ Parameters:
28
+ [TEXT] text to hide from an enemy
29
+
30
+ Options:
31
+ -f, --file FILE use a file as an input
32
+ -h, --help print help
33
+ ```
34
+
35
+ Alternatively you can use `Morseficator` module directly in your code:
36
+
37
+ ```ruby
38
+ irb(main):001:0> require 'morseficator'
39
+ => true
40
+ irb(main):002:0> Morseficator.run(text: 'HELLO WORLD')
41
+ => "4|1|1a2|1a2|c/1b|c|1a1|1a2|a2"
42
+ irb(main):003:0> Morseficator.run(file: '/path/to/file')
43
+ => "1a|3|a2\n1a|3|a2"
44
+ ```
45
+
46
+ ## Development
47
+
48
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
49
+
50
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
51
+
52
+ ## Contributing
53
+
54
+ Bug reports and pull requests are welcome on GitHub at https://github.com/duderman/morseficator.
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'morseficator'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'clamp'
6
+ require 'morseficator'
7
+
8
+ RED = '\033[0;31m'
9
+ NC = '\033[0m'
10
+
11
+ Clamp do
12
+ parameter '[TEXT]', 'text to hide from an enemy', attribute_name: :text
13
+ option ['-f', '--file'], 'FILE', 'use a file as an input', attribute_name: :file
14
+
15
+ def execute
16
+ puts Morseficator.run(text: text, file: file)
17
+ rescue Morseficator::Input::Error => e
18
+ signal_usage_error(red(e.message))
19
+ rescue Morseficator::Error => e
20
+ signal_error(red(e.message))
21
+ end
22
+
23
+ private
24
+
25
+ def red(message)
26
+ "\e[31m#{message}\e[0m"
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'morseficator/version'
4
+
5
+ # Main module
6
+ module Morseficator
7
+ class Error < StandardError; end
8
+
9
+ autoload :Encryptor, 'morseficator/encryptor.rb'
10
+ autoload :LetterEncoder, 'morseficator/letter_encoder.rb'
11
+ autoload :WordEncoder, 'morseficator/word_encoder.rb'
12
+ autoload :LineEncoder, 'morseficator/line_encoder.rb'
13
+ autoload :Encoder, 'morseficator/encoder.rb'
14
+ autoload :Input, 'morseficator/input.rb'
15
+
16
+ module_function
17
+
18
+ def run(text: nil, file: nil)
19
+ input = Input.build(text: text, file: file)
20
+ Encoder.encode(input)
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ # Encodes given input and prints it to output
5
+ class Encoder
6
+ def self.encode(*args)
7
+ new(*args).call
8
+ end
9
+
10
+ def initialize(input)
11
+ @input = input
12
+ end
13
+
14
+ def call
15
+ @input.map_lines { LineEncoder.encode(_1) }.join("\n")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ # Converts a single letter to a matching morse code
5
+ module Encryptor
6
+ CYPHER = {
7
+ 'A' => '1a',
8
+ 'B' => 'a3',
9
+ 'C' => 'a1a1',
10
+ 'D' => 'a2',
11
+ 'E' => '1',
12
+ 'F' => '2a1',
13
+ 'G' => 'b1',
14
+ 'H' => '4',
15
+ 'I' => '2',
16
+ 'J' => '1c',
17
+ 'K' => 'a1a',
18
+ 'L' => '1a2',
19
+ 'M' => 'b',
20
+ 'N' => 'a1',
21
+ 'O' => 'c',
22
+ 'P' => '1b1',
23
+ 'Q' => 'b1a',
24
+ 'R' => '1a1',
25
+ 'S' => '3',
26
+ 'T' => 'a',
27
+ 'U' => '2a',
28
+ 'V' => '3a',
29
+ 'W' => '1b',
30
+ 'X' => 'a2a',
31
+ 'Y' => 'a1b',
32
+ 'Z' => 'b2',
33
+ '0' => 'e',
34
+ '1' => '1d',
35
+ '2' => '2c',
36
+ '3' => '3b',
37
+ '4' => '4a',
38
+ '5' => '5',
39
+ '6' => 'a4',
40
+ '7' => 'b3',
41
+ '8' => 'c2',
42
+ '9' => 'd1'
43
+ }.freeze
44
+
45
+ module_function
46
+
47
+ def encrypt(letter)
48
+ raise(Morseficator::Error, "Argument isn't a string") unless letter.is_a?(String)
49
+ raise(Morseficator::Error, 'Only single letters are supported') if letter.length > 1
50
+
51
+ return '' if letter.empty?
52
+
53
+ CYPHER[letter.to_s] || raise(Morseficator::Error, "Unkonwn letter '#{letter}'")
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,22 @@
1
+ module Morseficator
2
+ # Input factory
3
+ module Input
4
+ class Error < Error; end
5
+
6
+ autoload :String, 'morseficator/input/string.rb'
7
+ autoload :File, 'morseficator/input/file.rb'
8
+
9
+ module_function
10
+
11
+ def build(text: nil, file: nil)
12
+ raise(Error, 'Missing an input') unless text || file
13
+ raise(Error, 'Chose either text or file input') if text && file
14
+
15
+ if text
16
+ String.new(text)
17
+ else
18
+ File.new(file)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ module Input
5
+ # Represents a file input
6
+ class File
7
+ def initialize(file)
8
+ @file = file
9
+ end
10
+
11
+ def map_lines(&block)
12
+ file.each_line.map { block.call(_1.chomp) }
13
+ end
14
+
15
+ private
16
+
17
+ def file
18
+ ::File.open(@file, 'r')
19
+ rescue Errno::ENOENT
20
+ raise(Morseficator::Input::Error, "File '#{@file}' wasn't found")
21
+ rescue Errno::EACCES
22
+ raise(Morseficator::Input::Error, "Don't have access to a file '#{@file}'")
23
+ rescue StandardError
24
+ raise(Morseficator::Input::Error, "Can't open file '#{@file}'")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ module Input
5
+ # String input adapter
6
+ class String
7
+ def initialize(string)
8
+ @string = string
9
+ end
10
+
11
+ def map_lines(&block)
12
+ @string.split("\n").map(&block)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ # Encodes a single letter
5
+ class LetterEncoder
6
+ def self.encode(*args)
7
+ new(*args).call
8
+ end
9
+
10
+ def initialize(letter)
11
+ @letter = letter
12
+ end
13
+
14
+ def call
15
+ Encryptor.encrypt(letter)
16
+ end
17
+
18
+ private
19
+
20
+ def letter
21
+ @letter.to_s.upcase
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ # Encodes a line of text word by word joining the result using a separator
5
+ class LineEncoder
6
+ def self.encode(*args)
7
+ new(*args).call
8
+ end
9
+
10
+ SEPARATOR = '/'
11
+ SPLIT_BY = ' '
12
+
13
+ def initialize(object)
14
+ @object = object
15
+ end
16
+
17
+ def call
18
+ entities.map { encoder.encode(_1) }.join(self.class::SEPARATOR)
19
+ end
20
+
21
+ private
22
+
23
+ def encoder
24
+ WordEncoder
25
+ end
26
+
27
+ def entities
28
+ @object.split(self.class::SPLIT_BY)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Morseficator
4
+ # Encodes a word letter by letter joining the result using a separator
5
+ class WordEncoder < LineEncoder
6
+ def self.encode(*args)
7
+ new(*args).call
8
+ end
9
+
10
+ SEPARATOR = '|'
11
+ SPLIT_BY = ''
12
+
13
+ private
14
+
15
+ def encoder
16
+ LetterEncoder
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/morseficator/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'morseficator'
7
+ spec.version = Morseficator::VERSION
8
+ spec.authors = ['Nikolay Norkin']
9
+ spec.email = ['zduderman@gmail.com']
10
+
11
+ spec.summary = 'Gem that can hide your communications from an enemy'
12
+ spec.description = 'Takes a message you are willing to send and encrypts
13
+ it using a top-secret algorithm'
14
+ spec.homepage = 'https://github.com/duderman/morseficator'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/duderman/morseficator'
19
+
20
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.executables = 'morseficator'
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_runtime_dependency 'bundler'
27
+ spec.add_runtime_dependency 'clamp', '~> 1.3'
28
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morseficator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nikolay Norkin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-10-04 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: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: clamp
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ description: |-
42
+ Takes a message you are willing to send and encrypts
43
+ it using a top-secret algorithm
44
+ email:
45
+ - zduderman@gmail.com
46
+ executables:
47
+ - morseficator
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".gitignore"
52
+ - ".rspec"
53
+ - ".rubocop.yml"
54
+ - Gemfile
55
+ - Gemfile.lock
56
+ - README.md
57
+ - Rakefile
58
+ - bin/console
59
+ - bin/morseficator
60
+ - bin/setup
61
+ - lib/morseficator.rb
62
+ - lib/morseficator/encoder.rb
63
+ - lib/morseficator/encryptor.rb
64
+ - lib/morseficator/input.rb
65
+ - lib/morseficator/input/file.rb
66
+ - lib/morseficator/input/string.rb
67
+ - lib/morseficator/letter_encoder.rb
68
+ - lib/morseficator/line_encoder.rb
69
+ - lib/morseficator/version.rb
70
+ - lib/morseficator/word_encoder.rb
71
+ - morseficator.gemspec
72
+ homepage: https://github.com/duderman/morseficator
73
+ licenses: []
74
+ metadata:
75
+ homepage_uri: https://github.com/duderman/morseficator
76
+ source_code_uri: https://github.com/duderman/morseficator
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 2.7.0
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubygems_version: 3.1.2
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Gem that can hide your communications from an enemy
96
+ test_files: []