rubyzip 0.5.12 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubyzip might be problematic. Click here for more details.

Files changed (43) hide show
  1. data/ChangeLog +151 -17
  2. data/NEWS +13 -0
  3. data/README +2 -0
  4. data/Rakefile +2 -3
  5. data/TODO +2 -3
  6. data/lib/download_quizzes.rb +119 -0
  7. data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +205 -0
  8. data/lib/quiz1/t/solutions/Carlos/solitaire.rb +111 -0
  9. data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +111 -0
  10. data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +301 -0
  11. data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +268 -0
  12. data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +132 -0
  13. data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +13 -0
  14. data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +230 -0
  15. data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +24 -0
  16. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +30 -0
  17. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +19 -0
  18. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +31 -0
  19. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +66 -0
  20. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +17 -0
  21. data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +2 -0
  22. data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +204 -0
  23. data/lib/quiz1/t/solutions/Jim Menard/test.rb +47 -0
  24. data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +97 -0
  25. data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +140 -0
  26. data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +14 -0
  27. data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +68 -0
  28. data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +146 -0
  29. data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +38 -0
  30. data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +5 -0
  31. data/lib/quiz1/t/solutions/Moses Hohman/util.rb +27 -0
  32. data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +151 -0
  33. data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +198 -0
  34. data/lib/zip/ioextras.rb +17 -15
  35. data/lib/zip/zip.rb +394 -112
  36. data/lib/zip/zipfilesystem.rb +2 -2
  37. data/test/gentestfiles.rb +3 -1
  38. data/test/zipfilesystemtest.rb +2 -2
  39. data/test/ziptest.rb +34 -29
  40. metadata +35 -12
  41. data/samples/zipdialogui.rb +0 -80
  42. data/test/data/file2.txt.other +0 -0
  43. data/test/zlibtest.rb +0 -26
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'util'
4
+
5
+ class TestArray < Test::Unit::TestCase
6
+ def test_peel_all_arrays_same_length
7
+ tuples = []
8
+ a1 = [1,3,5]
9
+ a2 = [2,4,6]
10
+ a3 = [1,4,9]
11
+ [a1, a2, a3].peel { |x,y,z| tuples << [x,y,z] }
12
+ assert_equal([[1,2,1],[3,4,4],[5,6,9]], tuples)
13
+ end
14
+
15
+ def test_peel_one_array_shorter
16
+ tuples = []
17
+ a1 = [1,3,5]
18
+ a2 = [2,4]
19
+ a3 = [1,4,9]
20
+ [a1, a2, a3].peel { |x,y,z| tuples << [x,y,z] }
21
+ assert_equal([[1,2,1],[3,4,4]], tuples)
22
+ end
23
+
24
+ def test_collect_peel
25
+ a1 = [1,3,5]
26
+ a2 = [2,4,6]
27
+ assert_equal([3,7,11], [a1, a2].collect_peel { |a,b| a+b })
28
+ end
29
+ end
30
+
31
+ class TestFixnum < Test::Unit::TestCase
32
+ def test_offset_mod
33
+ assert_equal(1, 27.offset_mod(26), "27 wrong")
34
+ assert_equal(26, 26.offset_mod(26), "26 wrong")
35
+ assert_equal(26, 0.offset_mod(26), "0 wrong")
36
+ assert_equal(25, -1.offset_mod(26), "-1 wrong")
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'test_cipher'
4
+ require 'test_deck'
5
+ require 'test_util'
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ class Array
4
+ # "Peels" off a tuple of the elements at each successive index across multiple arrays.
5
+ # Assumes self is an array of these multiple arrays. Stops when any of the arrays is
6
+ # exhausted. I stole this from a ruby mailing list somewhere. I also considered calling this each_tuple
7
+ def peel(&p)
8
+ collect { |a|
9
+ a.length
10
+ }.min.times { |i|
11
+ yield collect { |a| a[i] }
12
+ }
13
+ end
14
+
15
+ # syntactic sugar for Cipher
16
+ def collect_peel(&p)
17
+ collected = []
18
+ peel { |a,b| collected << p.call(a,b) }
19
+ collected
20
+ end
21
+ end
22
+
23
+ class Fixnum
24
+ def offset_mod(base)
25
+ ((self-1)%base)+1
26
+ end
27
+ end
@@ -0,0 +1,151 @@
1
+ def succ?(*a)
2
+ begin
3
+ (0..(a.size-2)).each {|i| return false if a[i].succ != a[i+1]}
4
+ return true
5
+ rescue
6
+ return false
7
+ end
8
+ end
9
+
10
+ class Deck
11
+ def initialize
12
+ @deck = (1..52).to_a + [:A, :B]
13
+ end
14
+
15
+ def move_a
16
+ move_down(@deck.index(:A))
17
+ end
18
+
19
+ def move_b
20
+ move_down(move_down(@deck.index(:B)))
21
+ end
22
+
23
+ def move_down(index)
24
+ if index < 53
25
+ new = index + 1
26
+ @deck[new], @deck[index] = @deck[index], @deck[new]
27
+ else
28
+ @deck = @deck[0,1] + @deck[-1,1] + @deck[1..-2]
29
+ new = 1
30
+ end
31
+ return new
32
+ end
33
+
34
+ def triple_cut
35
+ jokers = [@deck.index(:A), @deck.index(:B)]
36
+ top, bottom = jokers.min, jokers.max
37
+ @deck = @deck[(bottom+1)..-1] + @deck[top..bottom] + @deck[0...top]
38
+ end
39
+
40
+ def number_value(x)
41
+ return 53 if x == :A or x == :B
42
+ return x
43
+ end
44
+
45
+ def count_cut
46
+ count = number_value( @deck[-1] )
47
+ @deck = @deck[count..-2] + @deck[0,count] + @deck[-1,1]
48
+ end
49
+
50
+ def output
51
+ return @deck[ number_value(@deck[0]) ]
52
+ end
53
+
54
+ def update
55
+ move_a
56
+ move_b
57
+ triple_cut
58
+ count_cut
59
+ end
60
+
61
+ def get
62
+ while true
63
+ update
64
+ c = output
65
+ if c != :A and c != :B
66
+ letter = ( ((c-1) % 26) + 65 ).chr
67
+ return letter
68
+ end
69
+ end
70
+ end
71
+
72
+ def to_s
73
+ a = []
74
+ @deck.each_index {|i|
75
+ if succ?(a[-1], @deck[i], @deck[i+1])
76
+ a << "..."
77
+ elsif a[-1] == "..." and succ?(@deck[i-1], @deck[i], @deck[i+1])
78
+ # nop
79
+ else
80
+ a << @deck[i]
81
+ end
82
+ }
83
+ return a.join(" ")
84
+ end
85
+ end
86
+
87
+ class Encrypter
88
+ def initialize(keystream)
89
+ @keystream = keystream
90
+ end
91
+
92
+ def sanitize(s)
93
+ s = s.upcase
94
+ s = s.gsub(/[^A-Z]/, "")
95
+ s = s + "X" * ((5 - s.size % 5) % 5)
96
+ out = ""
97
+ (s.size / 5).times {|i| out << s[i*5,5] << " "}
98
+ return out
99
+ end
100
+
101
+ def mod(c)
102
+ return c - 26 if c > 26
103
+ return c + 26 if c < 1
104
+ return c
105
+ end
106
+
107
+ def process(s, &combiner)
108
+ s = sanitize(s)
109
+ out = ""
110
+ s.each_byte { |c|
111
+ if c >= ?A and c <= ?Z
112
+ key = @keystream.get
113
+ res = combiner.call(c, key[0])
114
+ out << res.chr
115
+ else
116
+ out << c.chr
117
+ end
118
+ }
119
+ return out
120
+ end
121
+
122
+ def encrypt(s)
123
+ return process(s) {|c, key| 64 + mod(c + key - 128)}
124
+ end
125
+
126
+ def decrypt(s)
127
+ return process(s) {|c, key| 64 + mod(c -key)}
128
+ end
129
+ end
130
+
131
+
132
+ def test
133
+ d = Deck.new()
134
+ d.update
135
+ puts d
136
+
137
+ e = Encrypter.new( Deck.new() )
138
+ cipher = e.encrypt('Code in Ruby, live longer!')
139
+ puts cipher
140
+
141
+ e = Encrypter.new( Deck.new() )
142
+ puts e.decrypt(cipher)
143
+
144
+ e = Encrypter.new( Deck.new() )
145
+ puts e.decrypt("CLEPK HHNIY CFPWH FDFEH")
146
+
147
+ e = Encrypter.new( Deck.new() )
148
+ puts e.decrypt("ABVAW LWZSY OORYK DUPVH")
149
+ end
150
+
151
+ test()
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'ostruct'
5
+
6
+ # Handles the deck
7
+ class Deck
8
+
9
+ # Initializes the deck with the default values
10
+ def initialize
11
+ @deck = (1..52).to_a << 'A' << 'B'
12
+ end
13
+
14
+ # Operation "move a" (step 2)
15
+ def move_A
16
+ move_down( @deck.index( 'A' ) )
17
+ end
18
+
19
+ # Operation "move b" (step 3)
20
+ def move_B
21
+ 2.times { move_down( @deck.index( 'B' ) ) }
22
+ end
23
+
24
+ # Operation "triple cut" (step 4)
25
+ def triple_cut
26
+ a = @deck.index( 'A' )
27
+ b = @deck.index( 'B' )
28
+ a, b = b, a if a > b
29
+ @deck.replace( [@deck[(b + 1)..-1], @deck[a..b], @deck[0...a]].flatten )
30
+ end
31
+
32
+ # Operation "count cut" (step 5)
33
+ def count_cut
34
+ temp = @deck[0..(@deck[-1] - 1)]
35
+ @deck[0..(@deck[-1] - 1)] = []
36
+ @deck[-1..-1] = [temp, @deck[-1]].flatten
37
+ end
38
+
39
+ # Operation "output the found letter" (step 6)
40
+ def output_letter
41
+ a = @deck.first
42
+ a = 53 if a.instance_of? String
43
+ output = @deck[a]
44
+ if output.instance_of? String
45
+ nil
46
+ else
47
+ output -= 26 if output > 26
48
+ (output + 64).chr
49
+ end
50
+ end
51
+
52
+ # Shuffle the deck using the initialization number +init+ and the method +method+.
53
+ # Currently there are only two methods: <tt>:fisher_yates</tt> and <tt>naive</tt>.
54
+ def shuffle( init, method = :fisher_yates )
55
+ srand( init )
56
+ self.send( method.id2name + "_shuffle", @deck )
57
+ end
58
+
59
+ private
60
+
61
+ # From pleac.sf.net
62
+ def fisher_yates_shuffle( a )
63
+ (a.size-1).downto(0) { |i|
64
+ j = rand(i+1)
65
+ a[i], a[j] = a[j], a[i] if i != j
66
+ }
67
+ end
68
+
69
+ # From pleac.sf.net
70
+ def naive_shuffle( a )
71
+ for i in 0...a.size
72
+ j = rand(a.size)
73
+ a[i], a[j] = a[j], a[i]
74
+ end
75
+ end
76
+
77
+ # Moves the index one place down while treating the used array as circular list.
78
+ def move_down( index )
79
+ if index == @deck.length - 1
80
+ @deck[1..1] = @deck[index], @deck[1]
81
+ @deck.pop
82
+ else
83
+ @deck[index], @deck[index + 1] = @deck[index + 1], @deck[index]
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+
90
+ # Implements the Solitaire Cipher algorithm
91
+ class SolitaireCipher
92
+
93
+ # Initialize the deck
94
+ def initialize( init = -1, method = :fisher_yates )
95
+ @deck = Deck.new
96
+ @deck.shuffle( init, method ) unless init == -1
97
+ end
98
+
99
+ # Decodes the given +msg+ using the internal deck
100
+ def decode( msg )
101
+ msgNumbers = to_numbers( msg )
102
+ cipherNumbers = to_numbers( generate_keystream( msg.length ) )
103
+
104
+ resultNumbers = []
105
+ msgNumbers.each_with_index do |item, index|
106
+ item += 26 if item <= cipherNumbers[index]
107
+ temp = item - cipherNumbers[index]
108
+ resultNumbers << temp
109
+ end
110
+
111
+ return to_chars( resultNumbers )
112
+ end
113
+
114
+ # Encodes the given +msg+ using the internal deck
115
+ def encode( msg )
116
+ msg = msg.gsub(/[^A-Za-z]/, '').upcase
117
+ msg += "X"*(5 - (msg.length % 5)) unless msg.length % 5 == 0
118
+
119
+ msgNumbers = to_numbers( msg )
120
+ cipherNumbers = to_numbers( generate_keystream( msg.length ) )
121
+
122
+ resultNumbers = []
123
+ msgNumbers.each_with_index do |item, index|
124
+ temp = item + cipherNumbers[index]
125
+ temp = temp - 26 if temp > 26
126
+ resultNumbers << temp
127
+ end
128
+
129
+ return to_chars( resultNumbers )
130
+ end
131
+
132
+ private
133
+
134
+ # Converts the string of uppercase letters into numbers (A=1, B=2, ...)
135
+ def to_numbers( chars )
136
+ chars.unpack("C*").collect {|x| x - 64}
137
+ end
138
+
139
+ # Converts the array of numbers to a string (1=A, 2=B, ...)
140
+ def to_chars( numbers )
141
+ numbers.collect {|x| x + 64}.pack("C*")
142
+ end
143
+
144
+ # Generates a keystream for the given +length+.
145
+ def generate_keystream( length )
146
+ deck = @deck.dup
147
+ result = []
148
+ while result.length != length
149
+ deck.move_A
150
+ deck.move_B
151
+ deck.triple_cut
152
+ deck.count_cut
153
+ letter = deck.output_letter
154
+ result << letter unless letter.nil?
155
+ end
156
+ result.join
157
+ end
158
+
159
+ end
160
+
161
+
162
+ options = OpenStruct.new
163
+ options.key = -1
164
+ options.shuffle = :fisher_yates
165
+ options.call_method = :decode
166
+
167
+ opts = OptionParser.new do |opts|
168
+ opts.banner = "Usage: #{File.basename($0, '.*')} [options] message"
169
+ opts.separator ""
170
+ opts.separator "Options:"
171
+ opts.on( "-d", "--decode", "Decode the message" ) do
172
+ options.call_method = :decode
173
+ end
174
+ opts.on( "-e", "--encode", "Encode the message" ) do
175
+ options.call_method = :encode
176
+ end
177
+ opts.on( "-k", "--key KEY", Integer, "Key for shuffling the deck" ) do |key|
178
+ options.key = key
179
+ end
180
+ opts.on( "-m", "--method METHOD", [:fisher_yates, :naive],
181
+ "Select the shuffling method (fisher_yates, naive" ) do |method|
182
+ options.shuffle = method
183
+ end
184
+ opts.on( "-h", "--help", "Show help" ) do
185
+ puts opts
186
+ exit
187
+ end
188
+ end
189
+
190
+
191
+ if ARGV.length == 0
192
+ puts opts
193
+ exit
194
+ end
195
+
196
+ message = opts.permute!( ARGV )[0]
197
+ cipher = SolitaireCipher.new( options.key, options.shuffle )
198
+ puts cipher.send( options.call_method, message )
data/lib/zip/ioextras.rb CHANGED
@@ -33,26 +33,28 @@ module IOExtras #:nodoc:
33
33
  attr_accessor :lineno
34
34
 
35
35
  def read(numberOfBytes = nil, buf = nil)
36
- buf = "" unless (buf)
36
+ tbuf = nil
37
37
 
38
- if numberOfBytes
38
+ if @outputBuffer.length > 0
39
39
  if numberOfBytes <= @outputBuffer.length
40
- buf[RANGE_ALL] = @outputBuffer.slice!(0, numberOfBytes)
40
+ tbuf = @outputBuffer.slice!(0, numberOfBytes)
41
41
  else
42
- if @outputBuffer.length > 0
43
- buf[RANGE_ALL] = @outputBuffer + sysread(numberOfBytes - @outputBuffer.length, buf)
44
- @outputBuffer.slice!(RANGE_ALL)
45
- else
46
- buf[RANGE_ALL] = sysread(nil, buf)
47
- end
42
+ numberOfBytes -= @outputBuffer.length if (numberOfBytes)
43
+ rbuf = sysread(numberOfBytes, buf)
44
+ tbuf = @outputBuffer
45
+ tbuf << rbuf if (rbuf)
46
+ @outputBuffer = ""
48
47
  end
49
48
  else
50
- if @outputBuffer.length > 0
51
- buf[RANGE_ALL] = @outputBuffer + sysread(nil, buf)
52
- @outputBuffer.slice!(RANGE_ALL)
53
- else
54
- buf[RANGE_ALL] = sysread(nil, buf)
55
- end
49
+ tbuf = sysread(numberOfBytes, buf)
50
+ end
51
+
52
+ return nil unless (tbuf)
53
+
54
+ if buf
55
+ buf.replace(tbuf)
56
+ else
57
+ buf = tbuf
56
58
  end
57
59
 
58
60
  buf