Gemnigma 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c972d271fb7395b7d645684a4e95991456479375
4
+ data.tar.gz: 85a3ca12bd9117a3d328386e7b0988ccca761b6e
5
+ SHA512:
6
+ metadata.gz: 7cfa961d91ed50852aadcc41edb87009787dc5190a4f5249505b4e9a77e031dc7209543e025ef04032e3c33de9d006a39c03dab3d02ed5b97ef8600b58525f68
7
+ data.tar.gz: d9728b6ff7bb168039d03489a441463c1e8f032674d6f7c618dcf7ad1e57883b877ba5850223b5adcfdf8d11b436758c70589f31c4614f4d809b263f9774c21f
data/.coveralls.yml ADDED
@@ -0,0 +1,2 @@
1
+ service_name: travis-ci
2
+ repo_token: TqZXn6K9ZgspMdKbRI1xJKQpKCmsVYtY8
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/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
4
+
5
+ cache: bundler
6
+
7
+ script: "bundle exec rake spec"
8
+
9
+ notifications:
10
+ email:
11
+ recipients:
12
+ - chinedudaniel72@yahoo.com
13
+ on_failure: change
14
+ on_success: never
15
+
16
+ after_success:
17
+ - coveralls
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in Gemnigma.gemspec
4
+ gemspec
data/Gemnigma.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'Gemnigma/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "Gemnigma"
8
+ spec.version = Gemnigma::VERSION
9
+ spec.authors = ["Chinedu"]
10
+ spec.email = ["chinedudaniel7@gmail.com"]
11
+ spec.summary = %q{ Encrypt and decrypt text files on your system }
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3"
23
+ spec.add_development_dependency "coveralls"
24
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Chinedu
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,87 @@
1
+ # Gemnigma [![Build Status](https://travis-ci.org/andela-cdaniel/Gemnigma.svg?branch=master)](https://travis-ci.org/andela-cdaniel/Gemnigma) [![Coverage Status](https://coveralls.io/repos/andela-cdaniel/Gemnigma/badge.svg?branch=master&service=github)](https://coveralls.io/github/andela-cdaniel/Gemnigma?branch=master)
2
+
3
+ The Gemnigma gem is an encryption engine for encoding messages. It is built using the Ruby programming language and intended to be used from within the command line.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'Gemnigma'
11
+ ```
12
+
13
+ And then execute from the command line:
14
+
15
+ $ bundle
16
+
17
+ Or install it directly from the command line yourself as:
18
+
19
+ $ gem install Gemnigma
20
+
21
+ ## How the encryption works
22
+
23
+ The encryption is based on rotation of letters based on a a key and the date that message was generated. The character map is made up of alphanumeric characters (alphabets all in lowercase), space character, period character and the comma character.
24
+
25
+ ### The Key
26
+
27
+ * Each message uses a unique encryption key
28
+ * The key is five digits, like 41521
29
+ * The first two digits of the key are the "A" rotation (41)
30
+ * The second and third digits of the key are the "B" rotation (15)
31
+ * The third and fourth digits of the key are the "C" rotation (52)
32
+ * The fourth and fifth digits of the key are the "D" rotation (21)
33
+
34
+ ### The Offset
35
+
36
+ * The date of message transmission is also factored into the encryption
37
+ * Consider the date in the format DDMMYY, like 020315
38
+ * Square the numeric form (412699225) and find the last four digits (9225)
39
+ * The first digit is the "A offset" (9)
40
+ * The second digit is the "B offset" (2)
41
+ * The third digit is the "C offset" (2)
42
+ * The fourth digit is the "D offset" (5)
43
+
44
+ ## Usage
45
+
46
+ Encrypt a message by providing an input file and an output file:
47
+
48
+ ```
49
+ Gemnigma encrypt message.txt encrypted.txt
50
+ ```
51
+
52
+ Decrypt a message by providing an input file, an output file, a key and a date offset:
53
+
54
+ ```
55
+ Gemnigma decrypt encrypted.txt decrypted.txt 41521 7225
56
+ ```
57
+
58
+ Crack a message when the key is not known by providing an input file, an
59
+ output file, and a date:
60
+
61
+ ```
62
+ Gemnigma crack encrypted.txt cracked.txt 51015
63
+ ```
64
+
65
+ List the contents of a directory by calling Gemnigma list and passing in options from "all", "file" or "folder"
66
+
67
+ ```
68
+ Gemnigma list file
69
+ ```
70
+
71
+ Call the help documentation at any time by typing Gemnigma help
72
+
73
+ ```
74
+ Gemnigma help
75
+ ```
76
+
77
+ ## Contributing
78
+
79
+ 1. Fork it: [Fork Gemnigma on Github](https://github.com/andela-cdaniel/Gemnigma/fork)
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
82
+ 4. Push to the branch (`git push origin my-new-feature`)
83
+ 5. Create a new Pull Request
84
+
85
+ ## License
86
+
87
+ Gemnigma is released under the [MIT License](https://github.com/andela-cdaniel/Gemnigma/blob/master/LICENSE.txt)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "rspec/core/rake_task"
2
+ require "bundler/gem_tasks"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |task|
5
+ task.rspec_opts = ['--color', '--format', 'doc']
6
+ end
7
+
8
+ task :default => :spec
data/bin/Gemnigma ADDED
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "Gemnigma"
4
+
5
+ class StartApplication
6
+ def init_application
7
+ @option = ARGV[0]
8
+
9
+ if ARGV.length == 0
10
+ help
11
+ end
12
+
13
+ if ARGV.length == 1
14
+ case @option
15
+ when "-v"
16
+ version
17
+ when "--version"
18
+ version
19
+ when "-h"
20
+ help
21
+ when "--help"
22
+ help
23
+ when "-ls"
24
+ list
25
+ when "list"
26
+ list
27
+ else
28
+ help
29
+ end
30
+ end
31
+
32
+ if ARGV.length > 1
33
+ case @option
34
+ when "-e"
35
+ encrypt
36
+ when "encrypt"
37
+ encrypt
38
+ when "-d"
39
+ decrypt
40
+ when "decrypt"
41
+ decrypt
42
+ when "-c"
43
+ crack
44
+ when "crack"
45
+ crack
46
+ when "-ls"
47
+ list
48
+ when "list"
49
+ list
50
+ else
51
+ help
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ private
58
+
59
+ def version
60
+ version = Gemnigma::VERSION
61
+ p version
62
+ end
63
+
64
+ def help
65
+ puts "Usage:\nGemnigma [option] [*arguments]"
66
+ puts "\nOptions:\n\t-h, [--help]" + "#Displays this help message and quits".rjust(50)
67
+ puts "\t-v, [--version]" + "#Display Gemnigma version number and quit".rjust(51)
68
+ puts "\t-ls,[list]" + "#List files in the current working directory".rjust(57)
69
+ puts "\t-e, [encrypt]" + "#Encrypt a file in the current directory".rjust(50)
70
+ puts "\t-d, [decrypt]" + "#Decrypt an encrypted file in the current directory".rjust(61)
71
+ puts "\t-c, [crack]" + "#Cracks an encrypted file in the current directory".rjust(62)
72
+
73
+ puts "\nEncrypting files:"
74
+ puts "To Encrypt files in the current directory, call Gemnigma -e or Gemnigma --encrypt and\npass in "\
75
+ "the file to be encrypted and a new file to store the encrypted message.\n\n"\
76
+ "Example:\n Gemnigma -e message.txt encrypted.txt"
77
+
78
+ puts "\nDecrypting files:"
79
+ puts "To decrypt files in the current directory, call Gemnigma -d or Gemnigma --decrypt and\n"\
80
+ "pass in the file to store the decrypted contents of an encrypted file, you are also\n"\
81
+ "required to pass in the date that the file was generated and the key used to generate\n"\
82
+ "the encrypted file.\n\n"\
83
+ "Example:\n Gemnigma -d encrypted.txt decrypted.txt 41521 #{Time.now.strftime("%d%m%y").to_i}"
84
+
85
+ puts "\nCracking files:"
86
+ puts "To crack files, call Gemnigma -c or Gemnigma --crack. You must specify the date encrypted"\
87
+ "file was generated and file to be written to\n\n"\
88
+ "Example:\nGemnigma -c encrypted.txt cracked.txt #{Time.now.strftime("%d%m%y").to_i}"
89
+ end
90
+
91
+ def encrypt
92
+ enc = Gemnigma::Encrypt.new
93
+ enc.get_cmd_args
94
+ end
95
+
96
+ def decrypt
97
+ dec = Gemnigma::Decrypt.new
98
+ dec.get_cmd_args
99
+ end
100
+
101
+ def crack
102
+ crack = Gemnigma::Crack.new
103
+ crack.get_cmd_args
104
+ end
105
+
106
+ def list_all
107
+ result = %x["ls"]
108
+ result_arr = result.split("\n")
109
+
110
+ result_arr.map! do |item|
111
+ if File.file? item
112
+ "[File] " + item
113
+ else
114
+ "[Folder] " + item
115
+ end
116
+ end
117
+ puts "All items in current working directory: \n\n"
118
+ puts result_arr
119
+ puts "\nTotal amount items in this directory: #{result_arr.length}"
120
+ end
121
+
122
+ def list_file
123
+ result = %x["ls"]
124
+ result_arr = result.split("\n")
125
+
126
+ result_arr.map! do |item|
127
+ if File.file? item
128
+ "[File] " + item
129
+ else
130
+ ""
131
+ end
132
+ end
133
+ puts "All files in current working directory: \n\n"
134
+ result_arr.delete("")
135
+ puts result_arr
136
+ puts "\nTotal amount of files in this directory: #{result_arr.length}"
137
+ end
138
+
139
+ def list_folder
140
+ result = %x["ls"]
141
+ result_arr = result.split("\n")
142
+ result_arr.map! do |item|
143
+ if File.directory? item
144
+ "[Folder] " + item
145
+ else
146
+ ""
147
+ end
148
+ end
149
+ puts "All folders in current working directory: \n\n"
150
+ result_arr.delete("")
151
+ puts result_arr
152
+ puts "\nTotal amount of folders in this directory: #{result_arr.length}"
153
+ end
154
+
155
+ def list_help
156
+ puts "Usage:\n Gemnigma list [option]"
157
+ puts "\nOptions:\n\thelp," + "#Displays this help message and quits".rjust(49)
158
+ puts "\tall," + "#Display all files and folder in the current working directory".rjust(75)
159
+ puts "\tfile," + "#Display only files in the current working directory".rjust(64)
160
+ puts "\tfolder," + "#Display all folders in the current working directory".rjust(63)
161
+ end
162
+
163
+ def list
164
+ list_all if ARGV.length == 1 || (ARGV.length == 2 && ARGV[1] == "all")
165
+
166
+ list_file if ARGV.length == 2 && ARGV[1] == "file"
167
+
168
+ list_folder if ARGV.length == 2 && ARGV[1] == "folder"
169
+
170
+ list_help if ARGV.length == 2 && ARGV[1] == "help"
171
+
172
+ if ARGV.length == 2 && !(ARGV[1] == "all" || ARGV[1] == "file" || ARGV[1] == "folder" || ARGV[1] == "help")
173
+ puts "Not a valid option"
174
+ end
175
+
176
+ if ARGV.length > 2
177
+ puts "Too many options passed in. Not valid"
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+ StartApplication.new.init_application
@@ -0,0 +1,11 @@
1
+ module Gemnigma
2
+ module CharMap
3
+ def self.generate_char_map
4
+ alphabets = ("a".."z")
5
+ numbers = ("0".."9")
6
+ others = [" ", ".", ","]
7
+ character_map = [alphabets.to_a, numbers.to_a, others].flatten
8
+ character_map
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "cipher_encrypt"
2
+
3
+ module Gemnigma
4
+ module CipherDecrypt
5
+ def self.rotate_backward(num)
6
+ CipherEncrypt.rotate_forward(num).invert
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require_relative "char_map"
2
+
3
+ module Gemnigma
4
+ module CipherEncrypt
5
+ def self.rotate_forward(num)
6
+ rotated = CharMap.generate_char_map.rotate(num)
7
+ Hash[CharMap.generate_char_map.zip(rotated)]
8
+ end
9
+ end
10
+ end
data/helpers/key.rb ADDED
@@ -0,0 +1,25 @@
1
+ module Gemnigma
2
+ class Key
3
+ attr_reader :key
4
+
5
+ def initialize(key=41521)
6
+ if (key.to_s.length == 5) && (key.class == Fixnum)
7
+ @key = key
8
+ else
9
+ puts "Not a valid key, defaulting to 41521"
10
+ @key = 41521
11
+ end
12
+ end
13
+
14
+ def key_map
15
+ generate_key_map
16
+ end
17
+
18
+ private
19
+
20
+ def generate_key_map
21
+ @key_map = @key.to_s.chars.each_cons(2).map(&:join).map(&:to_i)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ module Gemnigma
2
+ class Messages
3
+ def initialize(io=$stdout)
4
+ @io = io
5
+ end
6
+
7
+ def puts(msg)
8
+ @io.puts msg
9
+ end
10
+
11
+ def few_args
12
+ puts "Not enough arguments passed in. Run Gemnigma --help for instructions on usage\nExiting..."
13
+ end
14
+
15
+ def too_much_args
16
+ puts "Too many arguments passed in. Run Gemnigma --help for instructions on usage\nExiting..."
17
+ end
18
+
19
+ def file_not_in_existence(file)
20
+ puts "#{file}: File does not exist\nExiting..."
21
+ end
22
+
23
+ def file_in_existence(input_file, output_file)
24
+ puts "#{input_file} exists... Checking #{output_file}"
25
+ end
26
+
27
+ def creating_new_file(file)
28
+ puts "#{file} will be created, proceeding..."
29
+ end
30
+
31
+ def overwrite_warning(file)
32
+ puts "#{file} exists already, do you want to overwrite it? (Y) or (N): "
33
+ end
34
+
35
+ def wrong_date(date)
36
+ puts "#{date} doesn't match the specified date format\nExiting..."
37
+ end
38
+
39
+ def success_message(output_file, key, date)
40
+ puts "\n........................................................"
41
+ puts "\nCreated '#{output_file}' with secret key #{key} and date #{date}"
42
+ end
43
+ end
44
+ end
data/helpers/offset.rb ADDED
@@ -0,0 +1,26 @@
1
+ module Gemnigma
2
+ class Offset
3
+
4
+ def date
5
+ @current = Time.now
6
+ end
7
+
8
+ def offset
9
+ squared_date.to_s.chars.last(4).map(&:to_i)
10
+ end
11
+
12
+ def full_date
13
+ formatted_date
14
+ end
15
+
16
+ private
17
+
18
+ def formatted_date
19
+ date.strftime("%d%m%y").to_i
20
+ end
21
+
22
+ def squared_date
23
+ formatted_date ** 2
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "cipher_decrypt"
2
+ require_relative "rotator_encrypt"
3
+
4
+ module Gemnigma
5
+ class RotatorDecrypt < RotatorEncrypt
6
+ def rot_decrypt(word)
7
+ mapping = map_word_to_key(word)
8
+
9
+ mapping.map! do |arr|
10
+ Gemnigma::CipherDecrypt.rotate_backward(arr.last)[arr.first]
11
+ end
12
+
13
+ mapping.join
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,62 @@
1
+ require_relative "cipher_encrypt"
2
+ require_relative "key"
3
+ require_relative "offset"
4
+
5
+ module Gemnigma
6
+ class RotatorEncrypt
7
+ attr_reader :key_map
8
+
9
+ def initialize(key = Gemnigma::Key.new)
10
+
11
+ if key.methods.include? :key_map
12
+ @key_map = key.key_map
13
+ else
14
+ puts "Invalid key, using default key: 41521"
15
+ @key_map = Gemnigma::Key.new.key_map
16
+ end
17
+
18
+ end
19
+
20
+ def rot_encrypt(word)
21
+ mapping = map_word_to_key(word)
22
+
23
+ mapping.map! do |arr|
24
+ Gemnigma::CipherEncrypt.rotate_forward(arr.last)[arr.first]
25
+ end
26
+
27
+ mapping.join
28
+ end
29
+
30
+ private
31
+
32
+ def get_offset
33
+ Gemnigma::Offset.new.offset
34
+ end
35
+
36
+ def map_key_to_offset
37
+ @key_map.zip(get_offset)
38
+ end
39
+
40
+ def char_rotation
41
+ map_key_to_offset.map do |arr|
42
+ arr.inject(&:+)
43
+ end
44
+ end
45
+
46
+ def map_word_to_key(word)
47
+ result = []
48
+ count_key = 0
49
+
50
+ word.downcase.split("").each_with_index do |letter, index|
51
+ if count_key >= char_rotation.length
52
+ count_key = 0
53
+ end
54
+ result << [letter, char_rotation[count_key]]
55
+ count_key += 1
56
+ end
57
+
58
+ result
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,38 @@
1
+ require_relative "messages"
2
+
3
+ module Gemnigma
4
+ module ValidateFileArg
5
+ def validate
6
+ @input_file = ARGV[1]
7
+ @output_file = ARGV[2]
8
+
9
+ unless File.file? @input_file
10
+ Messages.new.file_not_in_existence(@input_file)
11
+ return
12
+ end
13
+
14
+ if File.file? @input_file
15
+ Messages.new.file_in_existence(@input_file, @output_file)
16
+ unless File.file? @output_file
17
+ Messages.new.creating_new_file(@output_file)
18
+ yield if block_given?
19
+ else
20
+ Messages.new.overwrite_warning(@output_file)
21
+ user_choice = $stdin.gets.chomp.downcase
22
+
23
+ if user_choice == "y"
24
+ yield if block_given?
25
+ elsif user_choice == "n"
26
+ puts "Operation aborted\nExiting..."
27
+ return
28
+ else
29
+ puts "Not a valid choice.\nOperation aborted.\nExiting..."
30
+ return
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end