rubyzip 0.9.1 → 2.3.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.
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