rubyzip 0.9.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +354 -0
  3. data/Rakefile +15 -104
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +212 -0
  6. data/lib/zip/compressor.rb +9 -0
  7. data/lib/zip/constants.rb +115 -0
  8. data/lib/zip/crypto/decrypted_io.rb +40 -0
  9. data/lib/zip/crypto/encryption.rb +11 -0
  10. data/lib/zip/crypto/null_encryption.rb +43 -0
  11. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  12. data/lib/zip/decompressor.rb +31 -0
  13. data/lib/zip/deflater.rb +34 -0
  14. data/lib/zip/dos_time.rb +53 -0
  15. data/lib/zip/entry.rb +719 -0
  16. data/lib/zip/entry_set.rb +88 -0
  17. data/lib/zip/errors.rb +19 -0
  18. data/lib/zip/extra_field/generic.rb +44 -0
  19. data/lib/zip/extra_field/ntfs.rb +94 -0
  20. data/lib/zip/extra_field/old_unix.rb +46 -0
  21. data/lib/zip/extra_field/universal_time.rb +77 -0
  22. data/lib/zip/extra_field/unix.rb +39 -0
  23. data/lib/zip/extra_field/zip64.rb +70 -0
  24. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  25. data/lib/zip/extra_field.rb +103 -0
  26. data/lib/zip/file.rb +468 -0
  27. data/lib/zip/filesystem.rb +643 -0
  28. data/lib/zip/inflater.rb +54 -0
  29. data/lib/zip/input_stream.rb +180 -0
  30. data/lib/zip/ioextras/abstract_input_stream.rb +122 -0
  31. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  32. data/lib/zip/ioextras.rb +21 -140
  33. data/lib/zip/null_compressor.rb +15 -0
  34. data/lib/zip/null_decompressor.rb +19 -0
  35. data/lib/zip/null_input_stream.rb +10 -0
  36. data/lib/zip/output_stream.rb +198 -0
  37. data/lib/zip/pass_thru_compressor.rb +23 -0
  38. data/lib/zip/pass_thru_decompressor.rb +31 -0
  39. data/lib/zip/streamable_directory.rb +15 -0
  40. data/lib/zip/streamable_stream.rb +52 -0
  41. data/lib/zip/version.rb +3 -0
  42. data/lib/zip.rb +72 -0
  43. data/samples/example.rb +44 -32
  44. data/samples/example_filesystem.rb +16 -19
  45. data/samples/example_recursive.rb +54 -0
  46. data/samples/gtk_ruby_zip.rb +84 -0
  47. data/samples/qtzip.rb +25 -34
  48. data/samples/write_simple.rb +10 -13
  49. data/samples/zipfind.rb +38 -45
  50. metadata +182 -91
  51. data/ChangeLog +0 -1504
  52. data/NEWS +0 -144
  53. data/README +0 -72
  54. data/install.rb +0 -22
  55. data/lib/download_quizzes.rb +0 -119
  56. data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +0 -205
  57. data/lib/quiz1/t/solutions/Carlos/solitaire.rb +0 -111
  58. data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +0 -111
  59. data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +0 -301
  60. data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +0 -268
  61. data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +0 -132
  62. data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +0 -13
  63. data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +0 -230
  64. data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +0 -24
  65. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +0 -30
  66. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +0 -19
  67. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +0 -31
  68. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +0 -66
  69. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +0 -17
  70. data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +0 -2
  71. data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +0 -204
  72. data/lib/quiz1/t/solutions/Jim Menard/test.rb +0 -47
  73. data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +0 -97
  74. data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +0 -140
  75. data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +0 -14
  76. data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +0 -68
  77. data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +0 -146
  78. data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +0 -38
  79. data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +0 -5
  80. data/lib/quiz1/t/solutions/Moses Hohman/util.rb +0 -27
  81. data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +0 -151
  82. data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +0 -198
  83. data/lib/zip/stdrubyext.rb +0 -111
  84. data/lib/zip/tempfile_bugfixed.rb +0 -195
  85. data/lib/zip/zip.rb +0 -1847
  86. data/lib/zip/zipfilesystem.rb +0 -609
  87. data/lib/zip/ziprequire.rb +0 -90
  88. data/samples/gtkRubyzip.rb +0 -86
  89. data/test/alltests.rb +0 -9
  90. data/test/data/file1.txt +0 -46
  91. data/test/data/file1.txt.deflatedData +0 -0
  92. data/test/data/file2.txt +0 -1504
  93. data/test/data/notzippedruby.rb +0 -7
  94. data/test/data/rubycode.zip +0 -0
  95. data/test/data/rubycode2.zip +0 -0
  96. data/test/data/testDirectory.bin +0 -0
  97. data/test/data/zipWithDirs.zip +0 -0
  98. data/test/gentestfiles.rb +0 -157
  99. data/test/ioextrastest.rb +0 -208
  100. data/test/stdrubyexttest.rb +0 -52
  101. data/test/zipfilesystemtest.rb +0 -831
  102. data/test/ziprequiretest.rb +0 -43
  103. data/test/ziptest.rb +0 -1599
@@ -1,111 +0,0 @@
1
- class Deck
2
- def initialize
3
- @deck = Array.new(54) {|i| i}
4
- end
5
-
6
- def create_keystream(count)
7
- stream = []
8
- count.times do
9
- letter = next_letter
10
- redo unless letter
11
- stream << letter
12
- end
13
- return stream
14
- end
15
-
16
- def next_letter
17
- ##
18
- # move the jokers
19
- ##
20
-
21
- 2.times do |j|
22
- # find the joker
23
- index = @deck.index(52 + j)
24
-
25
- # remove it from the deck
26
- @deck.delete_at(index)
27
-
28
- # calculate new index
29
- index = ((index + j) % 53) + 1
30
-
31
- # insert the joker at that index
32
- @deck[index, 0] = 52 + j
33
- end
34
-
35
- ##
36
- # do the tripple cut
37
- ##
38
-
39
- # first find both jokers
40
- a = @deck.index(52)
41
- b = @deck.index(53)
42
-
43
- # sort the two indeces
44
- low, hi = [a, b].sort
45
-
46
- # get the lower and upper parts of the deck
47
- upper = @deck.slice!((hi + 1)..-1)
48
- lower = @deck.slice!(0, low)
49
-
50
- # swap them
51
- @deck = upper + @deck + lower
52
-
53
- ##
54
- # do the count cut
55
- ##
56
-
57
- # find out the number of cards to cut
58
- count = value_at(53)
59
-
60
- # remove them from the top of the deck
61
- cards = @deck.slice!(0, count)
62
-
63
- # reinsert them just above the lowest card
64
- @deck[-1, 0] = cards
65
-
66
- return letter_at(value_at(0))
67
- end
68
-
69
- def value_at(index)
70
- id = @deck[index]
71
- (id > 51) ? 53 : id + 1
72
- end
73
-
74
- def letter_at(index)
75
- id = @deck[index]
76
- (id > 51) ? nil : (id % 26) + 1
77
- end
78
-
79
- def to_s
80
- @deck.map {|v| (v > 51) ? (v + 13).chr : (v + 1).to_s}.join(' ')
81
- end
82
- end
83
-
84
- def encode(data, keystream)
85
- result = []
86
- data.size.times {|i| result << ((data[i] + keystream[i]) % 26)}
87
- return result
88
- end
89
-
90
- def decode(data, keystream)
91
- encode(data, keystream.map {|v| 26 - v})
92
- end
93
-
94
- def data_to_string(data)
95
- data = data.map {|v| (v + 65).chr}.join
96
- (0...(data.size / 5)).map {|i| data[i * 5, 5]}.join(' ')
97
- end
98
-
99
- if ARGV.size != 1
100
- puts "Usage: solitaire.rb MESSAGE"
101
- exit
102
- end
103
-
104
- data = ARGV[0].upcase.split(//).select {|c| c =~ /[A-Z]/}.map {|c| c[0] - 65}
105
- data += [?X - 65] * (4 - (data.size + 4) % 5)
106
-
107
- deck = Deck.new
108
- keystream = deck.create_keystream(data.size)
109
-
110
- puts 'encoded:', data_to_string(encode(data, keystream))
111
- puts 'decoded:', data_to_string(decode(data, keystream))
@@ -1,301 +0,0 @@
1
- class Array
2
- # Moves the item from a specified index to
3
- # just before the item with the specified index.
4
- def move(from_index, to_index)
5
- from_index += self.size if from_index < 0
6
- to_index += self.size if to_index < 0
7
-
8
- item = self.slice!(from_index)
9
- self.insert(to_index, item)
10
- end
11
- end
12
-
13
- module Solitaire
14
- extend self
15
-
16
- Letters = ('A' .. 'Z').to_a
17
-
18
- class Card < Struct.new(:face, :type)
19
- Faces = [:ace, :two, :three, :four, :five, :six, :seven,
20
- :eight, :nine, :ten, :jack, :queen, :king]
21
- Types = [:clubs, :diamonds, :hearts, :spades, :special]
22
- SpecialFaces = [:joker_a, :joker_b]
23
-
24
- def self.deck
25
- Types.map do |type|
26
- if type == :special
27
- SpecialFaces.map do |face|
28
- new(face, type)
29
- end
30
- else
31
- Faces.map do |face|
32
- new(face, type)
33
- end
34
- end
35
- end.flatten
36
- end
37
-
38
- def special?; type == :special; end
39
-
40
- def value
41
- if special? then 53
42
- else
43
- Faces.index(face) + 1 + 13 * Types.index(type)
44
- end
45
- end
46
-
47
- def letter
48
- Letters[(value - 1) % 26]
49
- end
50
-
51
- def name
52
- if face == :joker_a then "JokerA"
53
- elsif face == :joker_b then "JokerB"
54
- else
55
- face_str = face.to_s.capitalize.gsub(/_(\w)/) { $1.upcase }
56
- type_str = type.to_s.capitalize
57
- face_str + " of " + type_str
58
- end
59
- end
60
-
61
- def compact_inspect
62
- if face == :joker_a then "A"
63
- elsif face == :joker_b then "B"
64
- else value end
65
- end
66
-
67
- def inspect
68
- "#<#{self.class} #{name} (#{letter}/#{value})>"
69
- end
70
- alias :to_s :inspect
71
-
72
- deck.each do |card|
73
- const_set(card.name.sub(" of ", "Of"), card)
74
- end
75
- end
76
-
77
- class KeyStream
78
- def initialize(key_method = nil)
79
- case key_method
80
- when true then
81
- @deck = Card.deck.sort_by { rand }
82
- when String then
83
- @deck = Card.deck
84
- generate_letter(key_method)
85
- else
86
- @deck = Card.deck
87
- end
88
- end
89
-
90
- def generate_letter(seed_phrase = nil)
91
- if seed_phrase
92
- seed_phrase = Solitaire.clean(seed_phrase)
93
- seed_phrase = nil if seed_phrase.empty?
94
- end
95
-
96
- result = nil
97
-
98
- until result
99
- deck_size = @deck.size
100
-
101
- # Move JokerA down one card
102
- old_a_pos = @deck.index(Card::JokerA)
103
- new_a_pos = case old_a_pos
104
- when deck_size - 1 then 1
105
- else old_a_pos + 1
106
- end
107
- @deck.move(old_a_pos, new_a_pos)
108
-
109
- # Move JokerB down two cards
110
- old_b_pos = @deck.index(Card::JokerB)
111
- new_b_pos = case old_b_pos
112
- when deck_size - 1 then 2
113
- when deck_size - 2 then 1
114
- else old_b_pos + 2
115
- end
116
- @deck.move(old_b_pos, new_b_pos)
117
-
118
- # Perform triple cut
119
- top_pos, bot_pos = [@deck.index(Card::JokerA), @deck.index(Card::JokerB)].sort
120
- @deck.replace(
121
- @deck[(bot_pos + 1) .. -1] +
122
- @deck[top_pos .. bot_pos] +
123
- @deck[0 ... top_pos])
124
-
125
- # Perform count cut
126
- top = @deck.slice!(0 ... @deck.last.value)
127
- @deck.insert(-2, *top)
128
-
129
- if seed_phrase
130
- key = seed_phrase.slice!(0, 1)
131
- top = @deck.slice!(0 ... Solitaire.letter_to_number(key))
132
- @deck.insert(-2, *top)
133
- result = true if seed_phrase.empty?
134
- else
135
- # Fetch result
136
- card = @deck[@deck.first.value]
137
- result = card.letter unless card.special?
138
- end
139
- end
140
-
141
- return result
142
- end
143
- alias :shift :generate_letter
144
- end
145
-
146
- def letter_to_number(letter)
147
- Letters.index(letter) + 1
148
- end
149
-
150
- def number_to_letter(number)
151
- Letters[number - 1]
152
- end
153
-
154
- def clean(text)
155
- text.upcase.delete("^A-Z")
156
- end
157
-
158
- def pretty(text)
159
- clean(text).scan(/.{1,5}/).join(" ")
160
- end
161
-
162
- def encrypt(raw_text, keystream = nil, pretty = true)
163
- keystream ||= KeyStream.new
164
- text = clean(raw_text)
165
- text += "X" * ((text.size / 5.0).ceil * 5 - text.size)
166
-
167
- result = ""
168
- 0.upto(text.size - 1) do |index|
169
- source_num = letter_to_number(text[index, 1])
170
- key_num = letter_to_number(keystream.shift)
171
- result << number_to_letter((source_num + key_num) % 26)
172
- end
173
-
174
- result = pretty(result) if pretty
175
- return result
176
- end
177
-
178
- def decrypt(raw_text, keystream = nil, pretty = true)
179
- keystream ||= KeyStream.new
180
- text = clean(raw_text)
181
-
182
- result = ""
183
- 0.upto(text.size - 1) do |index|
184
- source_num = letter_to_number(text[index, 1])
185
- key_num = letter_to_number(keystream.shift)
186
- result << number_to_letter((source_num - key_num) % 26)
187
- end
188
-
189
- result = pretty(result) if pretty
190
- return result
191
- end
192
- end
193
-
194
- if __FILE__ == $0
195
- require 'optparse'
196
-
197
- options = {
198
- :mode => nil,
199
- :keystream => nil,
200
- :keylength => 80,
201
- :text => nil
202
- }
203
-
204
- ARGV.options do |opts|
205
- script_name = File.basename($0)
206
- opts.banner = "Usage: ruby #{script_name} [options]"
207
-
208
- opts.separator ""
209
-
210
- opts.on("-d", "--decrypt",
211
- "Decrypt an encrypted message.",
212
- "This is the default if the message looks encrypted.") do
213
- options[:mode] = :decrypt
214
- end
215
- opts.on("-e", "--encrypt",
216
- "Encrypt an unencrypted message.") do
217
- options[:mode] = :encrypt
218
- end
219
- opts.on("-m", "--message message",
220
- "Specify the message.",
221
- "Default: Read from terminal.") do |text|
222
- options[:text] = text
223
- end
224
- opts.on("-k", "--key=key",
225
- "Specify the key that will be used for shuffling the deck.",
226
- "Default: Use an unshuffled deck.") do |key|
227
- options[:keystream] = Solitaire::KeyStream.new(key)
228
- end
229
- opts.on("-R", "--random-key length", Integer,
230
- "Use a randomly generated key for shuffling the deck.",
231
- "The key length can be specified. It defaults to 80.",
232
- "The key will be printed to the first line of STDOUT.") do |width|
233
- options[:keylength] = width if width
234
- options[:keystream] = :random
235
- end
236
- opts.on("-W", "--word-key file",
237
- "Use a randomly generated key phrase.",
238
- "It will consist of random words in the specified file.",
239
- "The key length can be specified via the -R option.",
240
- "The key phrase and the key will be printed to STDOUT.") do |word_file|
241
- options[:keystream] = :random_words
242
- options[:word_file] = word_file
243
- end
244
-
245
- opts.separator ""
246
-
247
- opts.on("-h", "--help",
248
- "Show this help message.") do
249
- puts opts; exit
250
- end
251
-
252
- opts.parse!
253
- end
254
-
255
- input = options[:text] || STDIN.read
256
-
257
- options[:mode] = :decrypt if /\A(?:[A-Z]{5}\s*)+\Z/.match(input)
258
-
259
- case options[:keystream]
260
- when :random then
261
- key = Array.new(options[:keylength]) { Solitaire::Letters[rand(26)] }.join
262
-
263
- puts "Key: " + Solitaire.pretty(key)
264
- options[:keystream] = Solitaire::KeyStream.new(key)
265
- when :random_words then
266
- begin
267
- words = File.read(options[:word_file]).scan(/\w+/)
268
- rescue
269
- STDERR.puts "Word file doesn't exist or can't be read."
270
- exit -1
271
- end
272
-
273
- words_size = words.size
274
-
275
- min_words = options[:keylength] / 6
276
- if words_size < min_words
277
- STDERR.puts "Word file must contain at least #{min_words} words," +
278
- " but it contains only #{words_size} words!"
279
- exit -2
280
- end
281
-
282
- key = []
283
- until key.join("").length >= options[:keylength]
284
- key << words[rand(words_size)]
285
- end
286
- key = key.join(" ")
287
-
288
- puts "Keyphrase: " + key
289
- puts "Key: " + Solitaire.pretty(key)
290
- options[:keystream] = Solitaire::KeyStream.new(key)
291
- end
292
-
293
- if options[:mode] == :decrypt
294
- puts Solitaire.decrypt(input, options[:keystream])
295
- else
296
- unless options[:keystream]
297
- STDERR.puts "WARNING: Using an unshuffled deck for encrypting!"
298
- end
299
- puts Solitaire.encrypt(input, options[:keystream])
300
- end
301
- end
@@ -1,268 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # Solitaire Cipher
3
- # Ruby-lang quiz #1
4
- # Solution by Glenn M. Lewis - 9/27/04
5
-
6
- $debug = nil
7
-
8
- class Card
9
- attr_reader :value, :face_value, :suit
10
-
11
- def initialize(face_value, suit)
12
- @face_value = face_value
13
- @suit = suit
14
- if suit then
15
- @value = calc_value(face_value, suit)
16
- return
17
- end
18
- case face_value
19
- when "AJoker"
20
- @value = 53
21
- when "BJoker"
22
- @value = 53
23
- else
24
- puts "ERROR: Unknown joker: #{joker}, should be 'AJoker' or 'BJoker'"
25
- exit
26
- end
27
- end
28
-
29
- def calc_value(face_value, suit)
30
- val = 0
31
- case suit
32
- when "S" then val += 39
33
- when "H" then val += 26
34
- when "D" then val += 13
35
- when "C"
36
- else
37
- puts "ERROR: Unknown suit: #{suit}, should be C,D,H,S"
38
- end
39
- case face_value
40
- when 2..10 then val += face_value
41
- when "A" then val += 1
42
- when "J" then val += 11
43
- when "Q" then val += 12
44
- when "K" then val += 13
45
- else
46
- puts "ERROR: Unknown card face value: #{face_value}, should be A,2-10,J,Q,K"
47
- end
48
- return val
49
- end
50
- end
51
-
52
- class Deck < Array
53
- def initialize
54
- ["C", "D", "H", "S"].each do |suit|
55
- ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K"].each do |face_value|
56
- self.push(Card.new(face_value, suit))
57
- end
58
- end
59
- self.push(Card.new("AJoker", nil))
60
- self.push(Card.new("BJoker", nil))
61
- @deck_size = self.size
62
- end
63
-
64
- def dump
65
- self.each do |c|
66
- if (c.value == 53)
67
- print c.face_value
68
- else
69
- print c.value
70
- end
71
- print " "
72
- end
73
- print "\n\n"
74
- if (@deck_size != self.size) then
75
- puts "ERROR! Deck size changed to #{self.size}"
76
- exit
77
- end
78
- end
79
-
80
- def find_joker(j)
81
- self.each_index do |i|
82
- if (self[i].face_value == j)
83
- return i
84
- end
85
- end
86
- puts "ERROR: Could not find joker '#{j}' in deck."
87
- end
88
-
89
- def move_card_down(pos, num)
90
- print "before move_card_down(#{pos}, #{num}): " if $debug
91
- self.dump if $debug
92
- dest = pos + num
93
- dest -= (self.size-1) if (dest >= self.size)
94
- card = self.delete_at(pos)
95
- temp = self.dup
96
- self.clear
97
- temp.slice(0, dest).each {|x| self.push(x) }
98
- self << card
99
- temp.slice(dest..(-1)).each {|x| self.push(x) }
100
- print "after move_card_down(#{pos}, #{num}): " if $debug
101
- self.dump if $debug
102
- end
103
-
104
- def triple_cut_split(a, b)
105
- a,b=b,a if (a > b)
106
- print "before triple_cut_split(#{a}, #{b}): " if $debug
107
- self.dump if $debug
108
- temp = self.dup
109
- self.clear
110
- temp.slice((b+1)..-1).each {|x| self.push(x) }
111
- temp.slice(a..b).each {|x| self.push(x) }
112
- temp.slice(0..(a-1)).each {|x| self.push(x) }
113
- print "after triple_cut_split(#{a}, #{b}): " if $debug
114
- self.dump if $debug
115
- end
116
-
117
- def count_cut
118
- print "before count_cut: " if $debug
119
- self.dump if $debug
120
- temp = self.dup
121
- self.clear
122
- num = temp[-1].value
123
- temp.slice(num..-2).each {|x| self.push(x) }
124
- temp.slice(0..(num-1)).each {|x| self.push(x) }
125
- self.push(temp[-1])
126
- print "after count_cut: " if $debug
127
- self.dump if $debug
128
- end
129
-
130
- def output_letter
131
- num = self[0].value
132
- card = self[num]
133
- return nil if (card.value == 53)
134
- num = (card.value > 26 ? card.value-26 : card.value)
135
- char = (num-1 + "A"[0]).chr
136
- puts "card.value=#{card.value}, char=#{char}" if $debug
137
- return char
138
- end
139
-
140
- def keystream_message(msg)
141
- # result = "DWJXHYRFDGTMSHPUURXJ"
142
- result = ""
143
- while (result.length < msg.length) do
144
- # Step 2 - Move the A Joker down one card
145
- pos = find_joker("AJoker")
146
- move_card_down(pos, 1)
147
- # Step 3 - Move the B Joker down two cards
148
- pos = find_joker("BJoker")
149
- move_card_down(pos, 2)
150
- # Step 4 - Triple cut split around two jokers
151
- apos = find_joker("AJoker")
152
- bpos = find_joker("BJoker")
153
- triple_cut_split(apos, bpos)
154
- # Step 5 - Count cut
155
- count_cut
156
- # Step 6 - Output letter - might be nil
157
- letter = output_letter
158
- result << letter if letter
159
- end
160
- return result
161
- end
162
- end
163
-
164
- message = ARGV[0].dup
165
-
166
- encrypted = true
167
- encrypted = false if (message =~ /[a-z]/)
168
- words = message.split(/\s+/)
169
- words.each do |word|
170
- encrypted = false if (word.length != 5)
171
- encrypted = false if (word =~ /[^A-Z]/)
172
- end
173
-
174
- def message2nums(msg)
175
- result = []
176
- msg.each_byte do |c|
177
- result.push(c+1-"A"[0])
178
- end
179
- return result
180
- end
181
-
182
- def nums2message(nums)
183
- result = ""
184
- nums.each do |val|
185
- result << (val-1+"A"[0]).chr
186
- end
187
- return result
188
- end
189
-
190
- deck = Deck.new
191
-
192
- if encrypted then
193
- puts "Encrypted message: '#{message}'"
194
- message.gsub!(/[^A-Z]/, '')
195
-
196
- # Step 1
197
- keystream_message = deck.keystream_message(message)
198
- # puts "keystream_message = #{keystream_message}"
199
-
200
- # Step 2
201
- num_message = message2nums(message)
202
- # puts "num_message = "
203
- # p num_message
204
-
205
- # Step 3
206
- num_keystream = message2nums(keystream_message)
207
- # puts "num_keystream = "
208
- # p num_keystream
209
-
210
- # Step 4
211
- num_result = []
212
- num_message.each_index do |index|
213
- num_result[index] = num_message[index] - num_keystream[index]
214
- num_result[index] += 26 if (num_result[index] < 1)
215
- end
216
-
217
- # Step 6
218
- result = nums2message(num_result)
219
- print "Unencrypted message: "
220
- count = 0
221
- result.each_byte do |c|
222
- print c.chr
223
- count += 1
224
- print " " if ((count % 5) == 0)
225
- end
226
- print "\n"
227
-
228
- else
229
- puts "Unencrypted message: '#{message}'"
230
-
231
- # Step 1
232
- message.upcase!
233
- message.gsub!(/[^A-Z]/, '')
234
- message << "X" * ((message.length % 5)==0 ? 0 : (5-(message.length % 5)))
235
- # puts "message: #{message}"
236
-
237
- # Step 2
238
- keystream_message = deck.keystream_message(message)
239
- # puts "keystream_message = #{keystream_message}"
240
-
241
- # Step 3
242
- num_message = message2nums(message)
243
- # puts "num_message = "
244
- # p num_message
245
-
246
- # Step 4
247
- num_keystream = message2nums(keystream_message)
248
- # puts "num_keystream = "
249
- # p num_keystream
250
-
251
- # Step 5
252
- num_result = []
253
- num_message.each_index do |index|
254
- num_result[index] = num_message[index] + num_keystream[index]
255
- num_result[index] -= 26 if (num_result[index] > 26)
256
- end
257
-
258
- # Step 6
259
- result = nums2message(num_result)
260
- print "Encrypted message: "
261
- count = 0
262
- result.each_byte do |c|
263
- print c.chr
264
- count += 1
265
- print " " if ((count % 5) == 0)
266
- end
267
- print "\n"
268
- end