morseficator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []