number_station 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 307e4f7227c11f3a5f102d751834125e78313460b0687db0b66fc27767119412
4
- data.tar.gz: fcc9d8d383ab9858bfb8b641598ccac627e8710d3486832cb96331bf9b44e6ef
3
+ metadata.gz: 12fbb0f21da5b3c4b4b30f59c3966b73f105b114598465657a00dde4602f2200
4
+ data.tar.gz: 016fe96066f8a08eae780630d2049537ebe6118af9c16cb37e0b2ea0acd3dbee
5
5
  SHA512:
6
- metadata.gz: 3604feb7f2e4e0a40c68d934112a0ca59b418b8a1858613f5e94e0d3b33933d9548cb316f63d64b1cde68dd7abe3e59c9ed4f1bd474d37503622037d086dc40c
7
- data.tar.gz: bee70668d29379c88b725ef7328a8a6af982b7299b888a6fbba7576f1da0f59c00451e04f0eb9e1df586bac4002274910fae7755c67290a85b650b4146d556a6
6
+ metadata.gz: ca0a3954b8b78bef7f6b96707ba33bf5806a760cb80db3ed6e4158952163b55afd5805991c5dff381832842dc822d0c1f1558cf85b56d5cad942b3a4d57c9276
7
+ data.tar.gz: f2a30d75eb9dadb26e3fdbcf277be8403ba0449e209517f4188ad10769522438852382c96103d8bb69c0991e4269a3d92676a4ccbda18458b75dba57ab9bb9a7
data/README.asciidoc CHANGED
@@ -1,6 +1,8 @@
1
1
  == number_station ==
2
2
  This gem (WIP) contains a number of utilities to aid in the running of a number station.
3
3
 
4
+ image:https://badge.fury.io/rb/number_station.svg["Gem Version", link="https://badge.fury.io/rb/number_station"]
5
+
4
6
  === Contributing ===
5
7
  Contributions are welcome, please fork the repo, create a branch, add your code, and make a PR
6
8
  against master on this repo.
data/config/conf.json CHANGED
@@ -7,6 +7,7 @@
7
7
  "port":8080
8
8
  },
9
9
  "resources":{
10
+ "espeak_sentence_template":"/tmp/GLaDOS_template.xml",
10
11
  "path":"resources",
11
12
  "intro":"intro.txt",
12
13
  "message":"message.txt",
@@ -25,6 +25,7 @@ require 'fileutils'
25
25
  module NumberStation
26
26
  class CLI < Thor
27
27
 
28
+
28
29
  # create_config
29
30
  desc "create_config [--path PATH]", "copy the sample config to current directory."
30
31
  long_desc <<-CREATE_CONFIG_LONG_DESC
@@ -59,20 +60,22 @@ module NumberStation
59
60
  end
60
61
 
61
62
 
62
- # convert_message
63
- desc "convert_message [MESSAGE]", "Convert a message to phonetic output."
63
+ # convert_to_phonetic
64
+ desc "convert_to_phonetic [MESSAGE]", "Convert a message to phonetic output."
64
65
  long_desc <<-CONVERT_MESSAGE_LONG_DESC
65
66
  convert_message takes a parameter which should point to a text file containing a message.
66
67
  Optional parameters:\n
68
+ MESSAGE\n
67
69
  --intro [INTRO] should be a text file containing intro message.\n
68
- --outro [OUTRO] should be a text file containing the outro message.
70
+ --outro [OUTRO] should be a text file containing the outro message.\n
71
+ --mp3 [MP3] output message as an mp3 file.
69
72
 
70
73
  Final message will be created from intro + message + outro
71
74
  CONVERT_MESSAGE_LONG_DESC
72
75
  option :intro, :type => :string
73
76
  option :outro, :type => :string
74
77
  option :mp3, :type => :string
75
- def convert_message(message)
78
+ def convert_to_phonetic(message)
76
79
  NumberStation::ConfigReader.read_config()
77
80
 
78
81
  intro_path = options[:intro]
@@ -82,38 +85,36 @@ module NumberStation
82
85
  NumberStation.log.debug "intro_path: #{intro_path}" if options[:intro]
83
86
  NumberStation.log.debug "message_path: #{message_path}"
84
87
  NumberStation.log.debug "outro_path: #{outro_path}" if options[:outro]
85
- NumberStation.log.debug "mp3_output: " if options[:mp3]
88
+ NumberStation.log.debug "mp3_path: #{mp3_path}" if options[:mp3]
86
89
 
87
90
  output = ""
88
- output += NumberStation.read_message(intro_path) if options[:intro]
89
- output += NumberStation.read_message(message_path)
90
- output += NumberStation.read_message(outro_path) if options[:outro]
91
-
91
+ output += NumberStation.to_phonetic(intro_path) if options[:intro]
92
+ output += NumberStation.to_phonetic(message_path)
93
+ output += NumberStation.to_phonetic(outro_path) if options[:outro]
92
94
  NumberStation.log.info "output: #{output}"
93
95
 
94
96
  if options[:mp3]
95
97
  NumberStation.log.debug "Generating mp3 output: #{mp3_path}"
96
- NumberStation.run(output, mp3_path)
98
+ NumberStation.write_mp3(output, mp3_path)
97
99
  end
98
-
99
100
  return output
100
101
  end
101
102
 
102
103
 
103
- # convert_message
104
- desc "make_one_time_pad [--path PATH --num NUM --length LENGTH]", "Generate a one time pad of LENGTH containing NUM entries"
104
+ # make_one_time_pad
105
+ desc "make_one_time_pad [--path PATH --numpads NUM --length LENGTH]", "Generate a one time pad of LENGTH containing NUM entries"
105
106
  long_desc <<-MAKE_ONE_TIME_PAD_LONG_DESC
106
107
  Generate a one time pad of LENGTH containing NUM entries
107
- Optional parameters:\n
108
+ Parameters:\n
108
109
  --path PATH\n
109
- --num NUM\n
110
+ --numpads NUM\n
110
111
  --length LENGTH
111
112
 
112
- If no parameters are passed it will generate a single one time pad in the current
113
+ If no parameters are passed it will generate 5 one time pads in the current
113
114
  directory of size 250 characters.
114
115
  MAKE_ONE_TIME_PAD_LONG_DESC
115
116
  option :length, :type => :numeric
116
- option :num_pads, :type => :numeric
117
+ option :numpads, :type => :numeric
117
118
  option :path, :type => :string
118
119
  def make_one_time_pad()
119
120
  NumberStation::ConfigReader.read_config()
@@ -122,13 +123,71 @@ module NumberStation
122
123
  length = options[:length]
123
124
  num_pads = options[:num_pads]
124
125
  path = options[:path]
125
-
126
126
  NumberStation.log.debug "length: #{length}" if options[:length]
127
- NumberStation.log.debug "num_pads: #{num_pads}" if options[:num_pads]
127
+ NumberStation.log.debug "numpads: #{numpads}" if options[:numpads]
128
128
  NumberStation.log.debug "path: #{path}" if options[:path]
129
129
 
130
130
  NumberStation.make_otp(path, length, num_pads)
131
131
  end
132
132
 
133
+
134
+ # encrypt message with a pad
135
+ desc "encrypt_message [MESSAGE --numpad NUMPAD --padpath PADPATH]", "Encrypt a message using the key: NUMPAD in one time pad PADPATH"
136
+ long_desc <<-ENCRYPT_MESSAGE_LONG_DESC
137
+ Encrypt a message using key NUMPAD in one-time-pad PADPATH
138
+ Parameters:\n
139
+ MESSAGE
140
+ --numpad NUMPAD\n
141
+ --padpath PADPATH
142
+
143
+ ENCRYPT_MESSAGE_LONG_DESC
144
+ option :numpad, :type => :string
145
+ option :padpath, :type => :string
146
+ def encrypt_message(message)
147
+ NumberStation::ConfigReader.read_config()
148
+ NumberStation.log.debug "encrypt_message"
149
+
150
+ message_data = File.read(message)
151
+ numpad = options[:numpad]
152
+ padpath = options[:padpath]
153
+
154
+ NumberStation.log.debug "message: #{message}" if options[:message]
155
+ NumberStation.log.debug "numpad: #{numpad}" if options[:numpad]
156
+ NumberStation.log.debug "padpath: #{padpath}" if options[:padpath]
157
+
158
+ enc_m = NumberStation.encrypt_message(message_data, padpath, numpad)
159
+ NumberStation.log.debug "encrypted_message: #{enc_m}"
160
+ end
161
+
162
+
163
+ # decrypt message with a pad
164
+ desc "encrypt_message [MESSAGE --numpad NUMPAD --padpath PADPATH]", "Decrypt a message using the key: NUMPAD in one time pad PADPATH"
165
+ long_desc <<-DECRYPT_MESSAGE_LONG_DESC
166
+ Encrypt a message using key NUMPAD in one-time-pad PADPATH
167
+ Parameters:\n
168
+ MESSAGE
169
+ --numpad NUMPAD\n
170
+ --padpath PADPATH
171
+
172
+ DECRYPT_MESSAGE_LONG_DESC
173
+ option :numpad, :type => :string
174
+ option :padpath, :type => :string
175
+ def decrypt_message(message)
176
+ NumberStation::ConfigReader.read_config()
177
+ NumberStation.log.debug "decrypt_message"
178
+
179
+ message_data = File.read(message)
180
+ numpad = options[:numpad]
181
+ padpath = options[:padpath]
182
+
183
+ NumberStation.log.debug "message: #{message}" if options[:message]
184
+ NumberStation.log.debug "numpad: #{numpad}" if options[:numpad]
185
+ NumberStation.log.debug "padpath: #{padpath}" if options[:padpath]
186
+
187
+ decrypt_m = NumberStation.decrypt_message(message_data, padpath, numpad)
188
+ NumberStation.log.debug "decrypted_message: #{decrypt_m}"
189
+ end
190
+
191
+
133
192
  end
134
193
  end
@@ -0,0 +1,71 @@
1
+ =begin
2
+ Ruby Number Station
3
+ Author: David Kirwan https://gitub.com/davidkirwan
4
+ Licence: GPL 3.0
5
+ NumberStation is a collection of utilities to aid in the running of a number station
6
+ Copyright (C) 2018 David Kirwan
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
20
+ =end
21
+ require "securerandom"
22
+ require "json"
23
+
24
+ module NumberStation
25
+
26
+ def self.decrypt_message(message, pad_path, pad_num)
27
+ message = message || "This is a secret message"
28
+ NumberStation.log.debug "message length: #{message.size}"
29
+ message_byte_array = message.scan(/.{1}/).each_slice(2).map { |f, l| (Integer(f,16) << 4) + Integer(l,16) }
30
+ #message.unpack('U*')
31
+ #NumberStation.log.debug "#{message_byte_array.inspect}"
32
+
33
+ begin
34
+ pad_data = JSON.parse(File.read(pad_path))
35
+ rescue Exception => e
36
+ raise e
37
+ end
38
+
39
+ #crypto_hex_str = SecureRandom.hex(message.size)
40
+ crypto_hex_str = pad_data["pads"][pad_num]
41
+
42
+ NumberStation.log.debug "message length less than pad length: #{message.size <= crypto_hex_str.size}"
43
+
44
+ #puts crypto_hex_str
45
+ crypto_byte_array = crypto_hex_str.scan(/.{1}/).each_slice(2).map { |f, l| (Integer(f,16) << 4) + Integer(l,16) }
46
+ #puts crypto_byte_array.inspect
47
+
48
+ #encrypted_byte_array = []
49
+ #message_byte_array.each_with_index do |i, index|
50
+ # encrypted_byte_array << (i ^ crypto_byte_array[index])
51
+ #end
52
+ #puts encrypted_byte_array.inspect
53
+
54
+ #encrypted_byte_str = encrypted_byte_array.each.map {|i| i.to_s(16)}.join
55
+ #encrypted_byte_array_two = encrypted_byte_str.scan(/.{1}/).each_slice(2).map { |f, l| (Integer(f,16) << 4) + Integer(l,16) }
56
+
57
+ decrypted_byte_array = []
58
+ message_byte_array.each_with_index do |i, index|
59
+ decrypted_byte_array << (i ^ crypto_byte_array[index])
60
+ end
61
+ #puts decrypted_byte_array.inspect
62
+
63
+ decrypted_string = decrypted_byte_array.pack('U*').force_encoding('utf-8')
64
+ #puts decrypted_string
65
+
66
+ #puts message == decrypted_string
67
+
68
+ return decrypted_string
69
+ end
70
+
71
+ end
@@ -0,0 +1,71 @@
1
+ =begin
2
+ Ruby Number Station
3
+ Author: David Kirwan https://gitub.com/davidkirwan
4
+ Licence: GPL 3.0
5
+ NumberStation is a collection of utilities to aid in the running of a number station
6
+ Copyright (C) 2018 David Kirwan
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
20
+ =end
21
+ require "securerandom"
22
+ require "json"
23
+
24
+ module NumberStation
25
+
26
+ def self.encrypt_message(message, pad_path, pad_num)
27
+ puts message
28
+ message = message || "This is a secret message"
29
+ NumberStation.log.debug "message length: #{message.size}"
30
+ message_byte_array = message.unpack('U*')
31
+ #NumberStation.log.debug "#{message_byte_array.inspect}"
32
+
33
+ begin
34
+ pad_data = JSON.parse(File.read(pad_path))
35
+ rescue Exception => e
36
+ raise e
37
+ end
38
+
39
+ #crypto_hex_str = SecureRandom.hex(message.size)
40
+ crypto_hex_str = pad_data["pads"][pad_num]
41
+
42
+ NumberStation.log.debug "message length less than pad length: #{message.size <= crypto_hex_str.size}"
43
+
44
+ #puts crypto_hex_str
45
+ crypto_byte_array = crypto_hex_str.scan(/.{1}/).each_slice(2).map { |f, l| (Integer(f,16) << 4) + Integer(l,16) }
46
+ #puts crypto_byte_array.inspect
47
+
48
+ encrypted_byte_array = []
49
+ message_byte_array.each_with_index do |i, index|
50
+ encrypted_byte_array << (i ^ crypto_byte_array[index])
51
+ end
52
+ #puts encrypted_byte_array.inspect
53
+
54
+ encrypted_byte_str = encrypted_byte_array.each.map {|i| i.to_s(16)}.join
55
+ #encrypted_byte_array_two = encrypted_byte_str.scan(/.{1}/).each_slice(2).map { |f, l| (Integer(f,16) << 4) + Integer(l,16) }
56
+
57
+ #decrypted_byte_array = []
58
+ #encrypted_byte_array_two.each_with_index do |i, index|
59
+ # decrypted_byte_array << (i ^ crypto_byte_array[index])
60
+ #end
61
+ #puts decrypted_byte_array.inspect
62
+
63
+ #decrypted_string = decrypted_byte_array.pack('U*').force_encoding('utf-8')
64
+ #puts decrypted_string
65
+
66
+ #puts message == decrypted_string
67
+
68
+ return encrypted_byte_str
69
+ end
70
+
71
+ end
@@ -24,8 +24,8 @@ require "json"
24
24
  module NumberStation
25
25
  def self.make_otp(pad_path, length, num_pads)
26
26
  path = pad_path || Dir.pwd
27
- len = length.to_i || 250
28
- num = num_pads.to_i || 5
27
+ len = length || 250
28
+ num = num_pads || 5
29
29
 
30
30
  NumberStation.log.debug "make_otp"
31
31
  pads = {}
@@ -33,7 +33,7 @@ module NumberStation
33
33
  file_name = File.join(path, "one_time_pad_#{id}.json")
34
34
  NumberStation.log.debug "file_name: #{file_name}"
35
35
 
36
- 0.upto(num - 1) {|i| pads[i] = SecureRandom.hex(len)}
36
+ 0.upto(num.to_i - 1) {|i| pads[i] = SecureRandom.hex(len.to_i)}
37
37
  one_time_pads = {
38
38
  :id=> id,
39
39
  :pads=> pads
@@ -46,6 +46,5 @@ module NumberStation
46
46
  else
47
47
  raise Exception.new("Exception #{file_name} already exists")
48
48
  end
49
-
50
49
  end
51
50
  end
@@ -60,7 +60,8 @@ module NumberStation
60
60
  'z' => "zulu"
61
61
  }
62
62
 
63
- def self.lookup(c)
63
+
64
+ def self.lookup_phonetic(c)
64
65
  begin
65
66
  return NumberStation::ALPHABET[c] + ' ' || ' '
66
67
  rescue Exception => e
@@ -68,4 +69,65 @@ module NumberStation
68
69
  end
69
70
  end
70
71
 
72
+
73
+ def self.espeak_word_template(word)
74
+ return "<prosody pitch=\"#{randomsign() + rand(0..200).to_s}\">#{word}</prosody>"
75
+ end
76
+
77
+
78
+ def self.randomsign()
79
+ return rand(0..1) == 0 ? "-" : "+"
80
+ end
81
+
82
+
83
+ def self.generate_sentence(message)
84
+ sentence = ""
85
+ message.split(" ").each {|i| sentence += espeak_word_template(i)}
86
+ return "<speak version=\"1.0\" xmlns=\"\" xmlns:xsi=\"\" xsi:schemaLocation=\"\" xml:lang=\"\"><voice gender=\"female\">#{sentence}</voice></speak>"
87
+ end
88
+
89
+
90
+ def self.write_espeak_template_file(filename, sentence)
91
+ f = File.open(filename, "w")
92
+ f.write(sentence)
93
+ f.close
94
+ end
95
+
96
+
97
+ def self.call_espeak(input_file_path, output_file_path)
98
+ cmd = "espeak -ven+f3 -m -p 60 -s 180 -f #{input_file_path} --stdout | ffmpeg -i - -ar 44100 -ac 2 -ab 192k -f mp3 #{output_file_path}"
99
+
100
+ unless NumberStation.command?('espeak') || NumberStation.command?('ffmpeg')
101
+ NumberStation.log.error "number_station requires the espeak and ffmpeg utilities are installed in order to output an mp3 file."
102
+ else
103
+ `#{cmd}`
104
+ end
105
+ end
106
+
107
+
108
+ def self.write_mp3(message, output_file_path)
109
+ filename = NumberStation.data["resources"]["espeak_sentence_template"]
110
+ sentence = NumberStation.generate_sentence(message)
111
+ NumberStation.write_espeak_template_file(filename, sentence)
112
+ NumberStation.call_espeak(filename, output_file_path)
113
+ end
114
+
115
+
116
+ def self.to_phonetic(file_name)
117
+ message = ''
118
+
119
+ f = File.open(file_name)
120
+ raw_message = f.readlines()
121
+ f.close()
122
+
123
+ raw_message.each do |i|
124
+ # puts i
125
+ i.gsub!(/\n/, "").strip.each_char do |c|
126
+ message += NumberStation.lookup_phonetic(c)
127
+ end
128
+ end
129
+ return message + "\n"
130
+ end
131
+
132
+
71
133
  end
@@ -20,5 +20,5 @@
20
20
  =end
21
21
 
22
22
  module NumberStation
23
- VERSION = "0.0.2"
23
+ VERSION = "0.0.3"
24
24
  end
@@ -21,10 +21,12 @@
21
21
  require 'pastel'
22
22
  require 'json'
23
23
  require 'logger'
24
- require 'number_station/alphabet'
25
24
  require 'number_station/cli'
26
25
  require 'number_station/config_reader'
27
- require 'number_station/make_pad'
26
+ require 'number_station/encrypt_message'
27
+ require 'number_station/decrypt_message'
28
+ require 'number_station/make_onetime_pad'
29
+ require 'number_station/phonetic_conversion'
28
30
  require 'number_station/version'
29
31
 
30
32
 
@@ -64,67 +66,4 @@ module NumberStation
64
66
  return @data
65
67
  end
66
68
 
67
- def self.word_template(word)
68
- return "<prosody pitch=\"#{randomsign + rand(0..200).to_s}\">#{word}</prosody>"
69
- end
70
-
71
-
72
- def self.randomsign()
73
- rand(0..1) == 0 ? "-" : "+"
74
- end
75
-
76
-
77
- def self.generate_sentence(message)
78
- sentence = ""
79
- message.split(" ").each do |i|
80
- sentence += word_template(i)
81
- end
82
-
83
- sentence_template = "<speak version=\"1.0\" xmlns=\"\" xmlns:xsi=\"\" xsi:schemaLocation=\"\" xml:lang=\"\"><voice gender=\"female\">#{sentence}</voice></speak>"
84
- return sentence_template
85
- end
86
-
87
-
88
- def self.write_template_file(filename, sentence)
89
- f = File.open(filename, "w")
90
- f.write(sentence)
91
- f.close
92
- end
93
-
94
-
95
- def self.call_espeak(input_file_path, output_file_path)
96
- cmd = "espeak -ven+f3 -m -p 60 -s 180 -f #{input_file_path} --stdout | ffmpeg -i - -ar 44100 -ac 2 -ab 192k -f mp3 #{output_file_path}"
97
-
98
- unless NumberStation.command?('espeak') || NumberStation.command?('ffmpeg')
99
- NumberStation.log.error "number_station requires the espeak and ffmpeg utilities are installed in order to output an mp3 file."
100
- else
101
- `#{cmd}`
102
- end
103
- end
104
-
105
-
106
- def self.run(message, output_file_path)
107
- filename = "/tmp/GLaDOS_tmp.xml"
108
- sentence = NumberStation.generate_sentence(message)
109
- NumberStation.write_template_file(filename, sentence)
110
- NumberStation.call_espeak(filename, output_file_path)
111
- end
112
-
113
-
114
- def self.read_message(file_name)
115
- message = ''
116
-
117
- f = File.open(file_name)
118
- raw_message = f.readlines()
119
- f.close()
120
-
121
- raw_message.each do |i|
122
- # puts i
123
- i.gsub!(/\n/, "").strip.each_char do |c|
124
- message += NumberStation.lookup(c)
125
- end
126
- end
127
- return message + "\n"
128
- end
129
-
130
69
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: number_station
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Kirwan
@@ -86,10 +86,12 @@ files:
86
86
  - bin/number_station
87
87
  - config/conf.json
88
88
  - lib/number_station.rb
89
- - lib/number_station/alphabet.rb
90
89
  - lib/number_station/cli.rb
91
90
  - lib/number_station/config_reader.rb
92
- - lib/number_station/make_pad.rb
91
+ - lib/number_station/decrypt_message.rb
92
+ - lib/number_station/encrypt_message.rb
93
+ - lib/number_station/make_onetime_pad.rb
94
+ - lib/number_station/phonetic_conversion.rb
93
95
  - lib/number_station/version.rb
94
96
  - number_station.gemspec
95
97
  - resources/body_message.txt