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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +6 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +37 -0
- data/README.md +54 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/morseficator +28 -0
- data/bin/setup +8 -0
- data/lib/morseficator.rb +22 -0
- data/lib/morseficator/encoder.rb +18 -0
- data/lib/morseficator/encryptor.rb +56 -0
- data/lib/morseficator/input.rb +22 -0
- data/lib/morseficator/input/file.rb +28 -0
- data/lib/morseficator/input/string.rb +16 -0
- data/lib/morseficator/letter_encoder.rb +24 -0
- data/lib/morseficator/line_encoder.rb +31 -0
- data/lib/morseficator/version.rb +5 -0
- data/lib/morseficator/word_encoder.rb +19 -0
- data/morseficator.gemspec +28 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -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__)
|
data/bin/morseficator
ADDED
@@ -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
|
data/bin/setup
ADDED
data/lib/morseficator.rb
ADDED
@@ -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,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: []
|