Gemnigma 0.0.2

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: 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