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
data/NEWS DELETED
@@ -1,144 +0,0 @@
1
- = Version 0.9.1
2
-
3
- Added symlink support and support for unix file permissions. Reduced
4
- memory usage during decompression.
5
-
6
- New methods ZipFile::[follow_symlinks, restore_times, restore_permissions, restore_ownership].
7
- New methods ZipEntry::unix_perms, ZipInputStream::eof?.
8
- Added documentation and test for new ZipFile::extract.
9
- Added some of the API suggestions from sf.net #1281314.
10
- Applied patch for sf.net bug #1446926.
11
- Applied patch for sf.net bug #1459902.
12
- Rework ZipEntry and delegate classes.
13
-
14
- = Version 0.5.12
15
-
16
- Fixed problem with writing binary content to a ZipFile in MS Windows.
17
-
18
- = Version 0.5.11
19
-
20
- Fixed name clash file method copy_stream from fileutils.rb. Fixed
21
- problem with references to constant CHUNK_SIZE.
22
- ZipInputStream/AbstractInputStream read is now buffered like ruby IO's
23
- read method, which means that read and gets etc can be mixed. The
24
- unbuffered read method has been renamed to sysread.
25
-
26
- = Version 0.5.10
27
-
28
- Fixed method name resolution problem with FileUtils::copy_stream and
29
- IOExtras::copy_stream.
30
-
31
- = Version 0.5.9
32
-
33
- Fixed serious memory consumption issue
34
-
35
- = Version 0.5.8
36
-
37
- Fixed install script.
38
-
39
- = Version 0.5.7
40
-
41
- install.rb no longer assumes it is being run from the toplevel source
42
- dir. Directory structure changed to reflect common ruby library
43
- project structure. Migrated from RubyUnit to Test::Unit format. Now
44
- uses Rake to build source packages and gems and run unit tests.
45
-
46
- = Version 0.5.6
47
-
48
- Fix for FreeBSD 4.9 which returns Errno::EFBIG instead of
49
- Errno::EINVAL for some invalid seeks. Fixed 'version needed to
50
- extract'-field incorrect in local headers.
51
-
52
- = Version 0.5.5
53
-
54
- Fix for a problem with writing zip files that concerns only ruby 1.8.1.
55
-
56
- = Version 0.5.4
57
-
58
- Significantly reduced memory footprint when modifying zip files.
59
-
60
- = Version 0.5.3
61
-
62
- Added optimization to avoid decompressing and recompressing individual
63
- entries when modifying a zip archive.
64
-
65
- = Version 0.5.2
66
-
67
- Fixed ZipFile corruption bug in ZipFile class. Added basic unix
68
- extra-field support.
69
-
70
- = Version 0.5.1
71
-
72
- Fixed ZipFile.get_output_stream bug.
73
-
74
- = Version 0.5.0
75
-
76
- List of changes:
77
- * Ruby 1.8.0 and ruby-zlib 0.6.0 compatibility
78
- * Changed method names from camelCase to rubys underscore style.
79
- * Installs to zip/ subdir instead of directly to site_ruby
80
- * Added ZipFile.directory and ZipFile.file - each method return an
81
- object that can be used like Dir and File only for the contents of the
82
- zip file.
83
- * Added sample application zipfind which works like Find.find, only
84
- Zip::ZipFind.find traverses into zip archives too.
85
-
86
- Bug fixes:
87
- * AbstractInputStream.each_line with non-default separator
88
-
89
-
90
- = Version 0.5.0a
91
-
92
- Source reorganized. Added ziprequire, which can be used to load ruby
93
- modules from a zip file, in a fashion similar to jar files in
94
- Java. Added gtkRubyzip, another sample application. Implemented
95
- ZipInputStream.lineno and ZipInputStream.rewind
96
-
97
- Bug fixes:
98
-
99
- * Read and write date and time information correctly for zip entries.
100
- * Fixed read() using separate buffer, causing mix of gets/readline/read to
101
- cause problems.
102
-
103
- = Version 0.4.2
104
-
105
- Performance optimizations. Test suite runs in half the time.
106
-
107
- = Version 0.4.1
108
-
109
- Windows compatibility fixes.
110
-
111
- = Version 0.4.0
112
-
113
- Zip::ZipFile is now mutable and provides a more convenient way of
114
- modifying zip archives than Zip::ZipOutputStream. Operations for
115
- adding, extracting, renaming, replacing and removing entries to zip
116
- archives are now available.
117
-
118
- Runs without warnings with -w switch.
119
-
120
- Install script install.rb added.
121
-
122
-
123
- = Version 0.3.1
124
-
125
- Rudimentary support for writing zip archives.
126
-
127
-
128
- = Version 0.2.2
129
-
130
- Fixed and extended unit test suite. Updated to work with ruby/zlib
131
- 0.5. It doesn't work with earlier versions of ruby/zlib.
132
-
133
-
134
- = Version 0.2.0
135
-
136
- Class ZipFile added. Where ZipInputStream is used to read the
137
- individual entries in a zip file, ZipFile reads the central directory
138
- in the zip archive, so you can get to any entry in the zip archive
139
- without having to skipping through all the preceeding entries.
140
-
141
-
142
- = Version 0.1.0
143
-
144
- First working version of ZipInputStream.
data/README DELETED
@@ -1,72 +0,0 @@
1
- = rubyzip
2
-
3
- rubyzip is a ruby library for reading and writing zip files.
4
-
5
- = Install
6
-
7
- If you have rubygems you can install rubyzip directly from the gem
8
- repository
9
-
10
- gem install rubyzip
11
-
12
- Otherwise obtain the source (see below) and run
13
-
14
- ruby install.rb
15
-
16
- To run the unit tests you need to have test::unit installed
17
-
18
- rake test
19
-
20
-
21
- = Documentation
22
-
23
- There is more than one way to access or create a zip archive with
24
- rubyzip. The basic API is modeled after the classes in
25
- java.util.zip from the Java SDK. This means there are classes such
26
- as Zip::ZipInputStream, Zip::ZipOutputStream and
27
- Zip::ZipFile. Zip::ZipInputStream provides a basic interface for
28
- iterating through the entries in a zip archive and reading from the
29
- entries in the same way as from a regular File or IO
30
- object. ZipOutputStream is the corresponding basic output
31
- facility. Zip::ZipFile provides a mean for accessing the archives
32
- central directory and provides means for accessing any entry without
33
- having to iterate through the archive. Unlike Java's
34
- java.util.zip.ZipFile rubyzip's Zip::ZipFile is mutable, which means
35
- it can be used to change zip files as well.
36
-
37
- Another way to access a zip archive with rubyzip is to use rubyzip's
38
- Zip::ZipFileSystem API. Using this API files can be read from and
39
- written to the archive in much the same manner as ruby's builtin
40
- classes allows files to be read from and written to the file system.
41
-
42
- rubyzip also features the
43
- zip/ziprequire.rb[link:files/lib/zip/ziprequire_rb.html] module which
44
- allows ruby to load ruby modules from zip archives.
45
-
46
- For details about the specific behaviour of classes and methods refer
47
- to the test suite. Finally you can generate the rdoc documentation or
48
- visit http://rubyzip.sourceforge.net.
49
-
50
- = License
51
-
52
- rubyzip is distributed under the same license as ruby. See
53
- http://www.ruby-lang.org/en/LICENSE.txt
54
-
55
-
56
- = Website and Project Home
57
-
58
- http://rubyzip.sourceforge.net
59
-
60
- http://sourceforge.net/projects/rubyzip
61
-
62
- == Download (tarballs and gems)
63
-
64
- http://sourceforge.net/project/showfiles.php?group_id=43107&package_id=35377
65
-
66
- = Authors
67
-
68
- Thomas Sondergaard (thomas at sondergaard.cc)
69
-
70
- Technorama Ltd. (oss-ruby-zip at technorama.net)
71
-
72
- extra-field support contributed by Tatsuki Sugiura (sugi at nemui.org)
data/install.rb DELETED
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $VERBOSE = true
4
-
5
- require 'rbconfig'
6
- require 'find'
7
- require 'ftools'
8
-
9
- include Config
10
-
11
- files = %w{ stdrubyext.rb ioextras.rb zip.rb zipfilesystem.rb ziprequire.rb tempfile_bugfixed.rb }
12
-
13
- INSTALL_DIR = File.join(CONFIG["sitelibdir"], "zip")
14
- File.makedirs(INSTALL_DIR)
15
-
16
- SOURCE_DIR = File.join(File.dirname($0), "lib/zip")
17
-
18
- files.each {
19
- |filename|
20
- installPath = File.join(INSTALL_DIR, filename)
21
- File::install(File.join(SOURCE_DIR, filename), installPath, 0644, true)
22
- }
@@ -1,119 +0,0 @@
1
- #!/bin/env ruby
2
-
3
- rubygems = false
4
- begin
5
- require 'rubygems'
6
- rubygems = true
7
- rescue LoadError
8
- end
9
-
10
- require 'open-uri'
11
- require 'fileutils'
12
-
13
- rubyzip = false
14
- begin
15
- require 'zip/zipfilesystem'
16
- rubyzip = true
17
- rescue LoadError
18
- end
19
-
20
-
21
- @address = "www.rubyquiz.com"
22
- first = last = nil
23
-
24
- first = ARGV[0].to_i if ARGV.size > 1
25
- last = ARGV[1].to_i if ARGV.size > 2
26
-
27
-
28
-
29
- #
30
- # Download a binary file from the rubyquiz url
31
- #
32
- def download(file, todir = '.')
33
- begin
34
- puts "Downloading file #{file} from #{@address}"
35
- c = open("http://#{@address}/#{file}").read
36
- Dir.mkdir(todir) if not File.directory?(todir)
37
- f = open("#{todir}/#{file}", 'wb')
38
- f.puts c
39
- f.close
40
- rescue => e
41
- if not File.exists?(fullfile)
42
- $stderr.puts "Could not download file #{file} form #{@address}."
43
- $stderr.puts e.to_s
44
- end
45
- end
46
- end
47
-
48
-
49
- #
50
- # Unzip the file using GNU's stand-alone unzip utility.
51
- #
52
- def unzip_gnu(file)
53
- puts `unzip -o #{file}`
54
- end
55
-
56
-
57
- #
58
- # Unzip the file using rubyzip library.
59
- #
60
- def unzip(x)
61
- outdir = x.sub(/.*\//, '')
62
- outdir = '.' if outdir == ""
63
- Zip::ZipFile::open(x) { |zf|
64
- zf.each { |e|
65
- fpath = File.join(outdir, e.name)
66
- FileUtils.mkdir_p(File.dirname(fpath))
67
- zf.extract(e, fpath)
68
- }
69
- }
70
- end
71
-
72
-
73
-
74
- def get_index
75
- c = open("http://#{@address}/").read
76
- quizzes = c.scan /quiz(\d+).html/
77
- return [ quizzes[0][0], quizzes[-1][0] ]
78
- end
79
-
80
- if not first or not last
81
- f, l = get_index()
82
- last = l unless last
83
- first = f unless first
84
- end
85
-
86
- first = first.to_i
87
- last = last.to_i
88
-
89
-
90
- puts "Downloading quizzess #{first} to #{last}"
91
- quizzes = (first..last)
92
- quizzes.each { |q|
93
- dir = "quiz#{q}"
94
-
95
- #### Download HTML description
96
- file = "quiz#{q}.html"
97
- fullfile = "#{dir}/#{file}"
98
- if not File.exists?(fullfile)
99
- download( file, dir )
100
- end
101
-
102
- #### Download zip file
103
- file = "quiz#{q}_sols.zip"
104
- fullfile = "#{dir}/#{file}"
105
-
106
- if not File.exists?(fullfile)
107
- download( file, dir )
108
- end
109
-
110
- # Unzip and remove .zip file
111
- Dir.chdir dir
112
- if rubyzip
113
- unzip file
114
- else
115
- unzip_gnu file
116
- end
117
- FileUtils.rm file
118
- Dir.chdir '..'
119
- }
@@ -1,205 +0,0 @@
1
- # bail if you have nothing to do.
2
- unless ARGV[0]
3
- print <<-STOP_PRINT
4
- Encrypts/decrypts a string of text.
5
- Usage: Give it some text!
6
- STOP_PRINT
7
- exit
8
- end
9
-
10
- # the obligatory deck of cards.
11
- ###############################################################################
12
- class Deck
13
- attr_reader :cards, :order
14
-
15
- def initialize
16
- @cards = []
17
- @order = []
18
- build_deck
19
- end
20
-
21
- def to_s
22
- return @cards.to_s
23
- end
24
-
25
- def build_deck
26
- [:Clubs, :Diamonds, :Hearts, :Spades].each do |suit|
27
- rank = 0
28
- 'A23456789TJQK'.each_byte do |name|
29
- # 'real' cards have a rank value
30
- rank += 1
31
- add_card(name.chr, suit, rank)
32
- end
33
- end
34
-
35
- # Jokers have no rank value
36
- 'AB'.each_byte {|name| add_card(name.chr, :Joker, 0)}
37
- end
38
-
39
- # build order while adding.
40
- def add_card(name, suit, rank)
41
- card = Card.new(name, suit, rank)
42
- @cards << card
43
- @order << card.to_s
44
- end
45
-
46
- # Uses order to hunt for cards (Joker searches).
47
- def find_card(name, suit)
48
- return @order.index(Card.to_s(name, suit))
49
- end
50
-
51
- # does as many cuts as you give it.
52
- def cut_cards(cuts)
53
- cards = []
54
- loc = 0
55
- [cuts].flatten.each_with_index do |cut, idx|
56
- cards[idx] = @cards[loc...cut]
57
- loc = cut
58
- end
59
- cards << @cards[loc...@cards.length]
60
- end
61
-
62
- def cards=(cards)
63
- # flatten to handle cut results.
64
- @cards = cards.flatten
65
- # rebuild @order each time the deck changes.
66
- update_order
67
- end
68
-
69
- # simple, but not very efficient.
70
- def update_order
71
- @order = @cards.collect {|card| card.to_s}
72
- end
73
-
74
- end
75
-
76
- # the above deck is made up of...
77
- ###############################################################################
78
- class Card
79
- @@SUITS = {
80
- :Clubs => 0,
81
- :Diamonds => 13,
82
- :Hearts => 26,
83
- :Spades => 39,
84
- :Joker => 53
85
- }
86
-
87
- def self.to_s(name, suit)
88
- return name + ' ' + suit.to_s + "\n"
89
- end
90
-
91
- attr_reader :name, :suit, :rank
92
-
93
- def initialize(name, suit, rank)
94
- @name = name
95
- @suit = suit
96
- @rank = rank + @@SUITS[suit]
97
- end
98
-
99
- def to_s
100
- Card.to_s(@name, @suit)
101
- end
102
- end
103
-
104
- ###############################################################################
105
- class Solitaire
106
-
107
- attr_reader :deck
108
-
109
- def initialize(text)
110
- @deck = Deck.new
111
- @text = text.to_s
112
- end
113
-
114
- def process
115
- # does it look encrypted? 5 letter blocks all uppercase?
116
- looks_encrypted = @text.gsub(/[A-Z]{5}\s?/, '').empty?
117
- results = ''
118
-
119
- # prep the text for parsing.
120
- if looks_encrypted
121
- # strip off the blanks for consistency
122
- text = @text.gsub(/\s/, '')
123
- else
124
- # Discard any non A to Z characters, and uppercase all remaining
125
- text = @text.upcase.gsub!(/[^A-Z]/, '')
126
- # Split the message into five character groups,
127
- words, padding = word_count(text, 5)
128
- # using Xs to pad the last group
129
- text += padding
130
- end
131
-
132
- # parse it, and build up results.
133
- text.each_byte do |char|
134
- if looks_encrypted
135
- char -= next_key
136
- char += 26 if char < 65
137
- else
138
- char += next_key
139
- char -= 26 if char > 90
140
- end
141
- results += char.chr
142
- end
143
-
144
- return space_text(results, 5)
145
- end
146
-
147
- # counts words as 5 char blocks
148
- def word_count(text, len)
149
- words, strays = text.length.divmod(len)
150
- words += 1 if strays > 0
151
- pad = "X" * (len - strays)
152
- return [words, pad]
153
- end
154
-
155
- def space_text(text, len)
156
- # adds a space every 5 letters.
157
- # not sure how efficient this is.
158
- return text.unpack(('A' + len.to_s) * word_count(text, len)[0]).join(' ')
159
- end
160
-
161
- def shift_card(name, suit, count)
162
- # find the card
163
- idx = @deck.find_card(name, suit)
164
- # remove it from the deck.
165
- card = @deck.cards.slice!(idx)
166
- # calculate new placement.
167
- idx += count
168
- # the slice above makes length 'look' zero-based
169
- idx -= @deck.cards.length if idx > @deck.cards.length
170
-
171
- # glue the deck together as cards before, card, cards after.
172
- @deck.cards = @deck.cards[0...idx] + [card] +
173
- @deck.cards[idx...@deck.cards.length]
174
- end
175
-
176
- def next_key
177
- shift_card('A', :Joker, 1)
178
- shift_card('B', :Joker, 2)
179
-
180
- # find the 2 jokers, and sort them for the cut.
181
- jokers = [@deck.find_card('A', :Joker), @deck.find_card('B', :Joker)].sort
182
- # increment the 2nd joker pos -- cut uses 'up to, but not including'
183
- jokers[1] += 1
184
- # reverse works nicely for the triple cut.
185
- @deck.cards = @deck.cut_cards(jokers).reverse
186
-
187
- # get the value from the last card, and cut up to it.
188
- cuts = @deck.cut_cards([@deck.cards.last.rank, @deck.cards.length - 1])
189
- @deck.cards = cuts[1] + cuts[0] + cuts[2]
190
-
191
- # read top card value, count down that many cards + 1
192
- key = @deck.cards[@deck.cards[0].rank].rank
193
- # convert it to a letter, adjust if needed.
194
- key -= 26 if key > 26
195
-
196
- # if key is still > 26, then it's a joker!
197
- return (key) unless key > 26
198
- # try again if it's a joker!
199
- next_key
200
- end
201
- end
202
-
203
- test = Solitaire.new(ARGV[0])
204
- puts test.process
205
- puts test.deck
@@ -1,111 +0,0 @@
1
- class Numeric
2
- def value
3
- self
4
- end
5
-
6
- def to_letter
7
- ((self-1)%26 + ?A).chr
8
- end
9
- end
10
-
11
- class String
12
- # returns an array with the code of the letters,
13
- # padded with the code of X
14
- def to_numbers
15
- res=upcase.unpack("C*").collect { |b|
16
- if b.between? ?A, ?Z
17
- b - ?A + 1
18
- else
19
- nil
20
- end
21
- }.compact
22
- # 24 == X
23
- res.fill 24, res.length, (5 - res.length % 5) % 5
24
- end
25
-
26
- def crypt (deck, decrypt=false)
27
- numbers = to_numbers
28
- keystream = deck.generate_keystream numbers.length
29
- result = ""
30
- numbers.zip(keystream) do |n, k|
31
- k = -k if decrypt
32
- result << (n+k).to_letter
33
- end
34
- result
35
- end
36
-
37
- def encrypt (deck)
38
- crypt deck, false
39
- end
40
-
41
- def decrypt (deck)
42
- crypt deck, true
43
- end
44
- end
45
-
46
- class Joker
47
- def value
48
- 53
49
- end
50
- end
51
-
52
- A = Joker.new
53
- B = Joker.new
54
-
55
- class Array
56
- def wrap_down pos
57
- pos %= length
58
- if pos == 0
59
- pos = length
60
- end
61
- pos
62
- end
63
-
64
- def next_key
65
- # step 2: move A joker down 1 card
66
- pos = index A
67
- slice! pos
68
- pos = wrap_down(pos + 1)
69
- self[pos, 0] = A
70
-
71
- # step 3: move B joker down 2 cards
72
- pos = index B
73
- slice! pos
74
- pos = wrap_down(pos + 2)
75
- self[pos, 0] = B
76
-
77
- # step 4: triple cut
78
- first_joker, second_joker = [index(A), index(B)].sort
79
- cards_above = slice! 0...first_joker
80
- second_joker -= cards_above.length
81
- cards_below = slice! second_joker+1..-1
82
- push *cards_above
83
- unshift *cards_below
84
-
85
- # step 5: count cut using the value of the bottom card.
86
- # reinsert above the last card
87
- cut = slice! 0, last.value
88
- self[-1,0] = cut
89
-
90
- # step 6: find the letter
91
- card = self[first.value]
92
-
93
- return Joker===card ? nil : card.value
94
- end
95
-
96
- def generate_keystream len
97
- (1..len).collect {|i| next_key or redo }
98
- end
99
- end
100
-
101
- def new_deck
102
- (1..52).to_a + [A, B]
103
- end
104
-
105
- res = if ARGV[0] == "-d"
106
- ARGV[1..-1].join("").decrypt(new_deck)
107
- else
108
- ARGV.join("").encrypt(new_deck)
109
- end
110
-
111
- puts res.scan(/.{5}/).join(" ")