facets 2.0.5 → 2.1.0
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.
- data/WHATSNEW +11 -0
- data/lib/core/facets/enumerable/collect.rb +7 -2
- data/lib/core/facets/enumerable/permutation.rb +7 -26
- data/lib/core/facets/module/alias.rb +36 -12
- data/lib/core/facets/module/attr.rb +83 -35
- data/lib/core/facets/module/include.rb +10 -0
- data/lib/methods/facets/module/alias_accessor.rb +1 -1
- data/lib/methods/facets/module/alias_reader.rb +1 -0
- data/lib/methods/facets/module/alias_setter.rb +1 -0
- data/lib/methods/facets/module/alias_switcher.rb +1 -0
- data/lib/methods/facets/module/alias_tester.rb +1 -0
- data/lib/methods/facets/module/alias_toggler.rb +1 -0
- data/lib/methods/facets/module/alias_validator.rb +1 -0
- data/lib/methods/facets/module/alias_writer.rb +1 -0
- data/lib/methods/facets/module/attr_accessor.rb +1 -0
- data/lib/methods/facets/module/attr_reader.rb +1 -0
- data/lib/methods/facets/module/attr_switcher.rb +1 -0
- data/lib/methods/facets/module/attr_writer.rb +1 -0
- data/lib/more/facets/arguments.rb +2 -1
- data/lib/more/facets/command.rb +258 -395
- data/lib/more/facets/crypt.rb +242 -28
- data/lib/more/facets/ziputils.rb +1 -1
- data/log/changelog.txt +0 -0
- data/log/history.txt +22 -0
- data/log/release.txt +10 -0
- data/log/todo.txt +4 -0
- data/meta/{facets-2.0.5.roll → facets-2.1.0.roll} +0 -0
- data/meta/google_ad.html +15 -0
- data/meta/icli.yaml +3 -3
- data/meta/manifest.txt +24 -3
- data/task/clobber/package +10 -0
- data/task/config/general.yaml +21 -3
- data/task/isotest +2 -1
- data/task/loadtest +2 -0
- data/task/prepare +4 -2
- data/task/rdoc +122 -73
- data/task/release +12 -0
- data/task/special/quickopts +15 -0
- data/task/syntax +2 -0
- data/task/test +3 -1
- data/test/unit/enumerable/test_collect.rb +17 -0
- data/test/unit/enumerable/test_permutation.rb +20 -30
- data/test/unit/test_crypt.rb +29 -36
- metadata +40 -12
- data/RELEASE +0 -12
- data/test/unit/test_command.rb +0 -286
data/lib/more/facets/crypt.rb
CHANGED
@@ -39,6 +39,7 @@
|
|
39
39
|
#
|
40
40
|
# - Poul-Henning Kamp
|
41
41
|
|
42
|
+
require 'stringio'
|
42
43
|
|
43
44
|
# = Crypt(3)
|
44
45
|
#
|
@@ -170,45 +171,258 @@ module Crypt
|
|
170
171
|
end
|
171
172
|
|
172
173
|
|
174
|
+
class BiCrypt
|
173
175
|
|
174
|
-
|
175
|
-
# |_ _|__ ___| |_
|
176
|
-
# | |/ _ \/ __| __|
|
177
|
-
# | | __/\__ \ |_
|
178
|
-
# |_|\___||___/\__|
|
179
|
-
#
|
176
|
+
ULONG = 0x100000000
|
180
177
|
|
181
|
-
|
178
|
+
def block_size
|
179
|
+
return(8)
|
180
|
+
end
|
182
181
|
|
183
|
-
|
182
|
+
def initialize(userKey)
|
183
|
+
|
184
|
+
# These are the S-boxes given in Applied Cryptography 2nd Ed., p. 333
|
185
|
+
@sBox = [
|
186
|
+
[4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3],
|
187
|
+
[14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9],
|
188
|
+
[5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11],
|
189
|
+
[7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3],
|
190
|
+
[6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2],
|
191
|
+
[4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14],
|
192
|
+
[13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12],
|
193
|
+
[1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12]
|
194
|
+
]
|
195
|
+
|
196
|
+
# These are the S-boxes given in the GOST source code listing in Applied
|
197
|
+
# Cryptography 2nd Ed., p. 644. They appear to be from the DES S-boxes
|
198
|
+
# [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 ],
|
199
|
+
# [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 ],
|
200
|
+
# [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 ],
|
201
|
+
# [ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 ],
|
202
|
+
# [ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 ],
|
203
|
+
# [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 ],
|
204
|
+
# [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 ],
|
205
|
+
# [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 ]
|
206
|
+
|
207
|
+
# precalculate the S table
|
208
|
+
@sTable = precalculate_S_table()
|
209
|
+
|
210
|
+
# derive the 32-byte key from the user-supplied key
|
211
|
+
userKeyLength = userKey.length
|
212
|
+
@key = userKey[0..31].unpack('C'*32)
|
213
|
+
if (userKeyLength < 32)
|
214
|
+
userKeyLength.upto(31) { @key << 0 }
|
215
|
+
end
|
216
|
+
end
|
184
217
|
|
185
|
-
class CryptTest < Test::Unit::TestCase
|
186
218
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
219
|
+
def precalculate_S_table()
|
220
|
+
sTable = [[], [], [], []]
|
221
|
+
0.upto(3) { |i|
|
222
|
+
0.upto(255) { |j|
|
223
|
+
t = @sBox[2*i][j % 16] | (@sBox[2*i+1][j/16] << 4)
|
224
|
+
u = (8*i + 11) % 32
|
225
|
+
v = (t << u) | (t >> (32-u))
|
226
|
+
sTable[i][j] = (v % ULONG)
|
227
|
+
}
|
228
|
+
}
|
229
|
+
return(sTable)
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
def f(longWord)
|
234
|
+
longWord = longWord % ULONG
|
235
|
+
a, b, c, d = [longWord].pack('L').unpack('CCCC')
|
236
|
+
return(@sTable[3][d] ^ @sTable[2][c] ^ @sTable[1][b] ^ @sTable[0][a])
|
237
|
+
end
|
238
|
+
|
239
|
+
def encrypt_pair(xl, xr)
|
240
|
+
3.times {
|
241
|
+
xr ^= f(xl+@key[0])
|
242
|
+
xl ^= f(xr+@key[1])
|
243
|
+
xr ^= f(xl+@key[2])
|
244
|
+
xl ^= f(xr+@key[3])
|
245
|
+
xr ^= f(xl+@key[4])
|
246
|
+
xl ^= f(xr+@key[5])
|
247
|
+
xr ^= f(xl+@key[6])
|
248
|
+
xl ^= f(xr+@key[7])
|
249
|
+
}
|
250
|
+
xr ^= f(xl+@key[7])
|
251
|
+
xl ^= f(xr+@key[6])
|
252
|
+
xr ^= f(xl+@key[5])
|
253
|
+
xl ^= f(xr+@key[4])
|
254
|
+
xr ^= f(xl+@key[3])
|
255
|
+
xl ^= f(xr+@key[2])
|
256
|
+
xr ^= f(xl+@key[1])
|
257
|
+
xl ^= f(xr+@key[0])
|
258
|
+
return([xr, xl])
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
def decrypt_pair(xl, xr)
|
263
|
+
xr ^= f(xl+@key[0])
|
264
|
+
xl ^= f(xr+@key[1])
|
265
|
+
xr ^= f(xl+@key[2])
|
266
|
+
xl ^= f(xr+@key[3])
|
267
|
+
xr ^= f(xl+@key[4])
|
268
|
+
xl ^= f(xr+@key[5])
|
269
|
+
xr ^= f(xl+@key[6])
|
270
|
+
xl ^= f(xr+@key[7])
|
271
|
+
3.times {
|
272
|
+
xr ^= f(xl+@key[7])
|
273
|
+
xl ^= f(xr+@key[6])
|
274
|
+
xr ^= f(xl+@key[5])
|
275
|
+
xl ^= f(xr+@key[4])
|
276
|
+
xr ^= f(xl+@key[3])
|
277
|
+
xl ^= f(xr+@key[2])
|
278
|
+
xr ^= f(xl+@key[1])
|
279
|
+
xl ^= f(xr+@key[0])
|
280
|
+
}
|
281
|
+
return([xr, xl])
|
282
|
+
end
|
283
|
+
|
284
|
+
def encrypt_block(block)
|
285
|
+
xl, xr = block.unpack('NN')
|
286
|
+
xl, xr = encrypt_pair(xl, xr)
|
287
|
+
encrypted = [xl, xr].pack('NN')
|
288
|
+
return(encrypted)
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
def decrypt_block(block)
|
293
|
+
xl, xr = block.unpack('NN')
|
294
|
+
xl, xr = decrypt_pair(xl, xr)
|
295
|
+
decrypted = [xl, xr].pack('NN')
|
296
|
+
return(decrypted)
|
297
|
+
end
|
298
|
+
|
299
|
+
# When this module is mixed in with an encryption class, the class
|
300
|
+
# must provide three methods: encrypt_block(block) and decrypt_block(block)
|
301
|
+
# and block_size()
|
302
|
+
|
303
|
+
def generate_initialization_vector(words)
|
304
|
+
srand(Time.now.to_i)
|
305
|
+
vector = ""
|
306
|
+
words.times {
|
307
|
+
vector << [rand(ULONG)].pack('N')
|
308
|
+
}
|
309
|
+
return(vector)
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
def encrypt_stream(plainStream, cryptStream)
|
314
|
+
# Cypher-block-chain mode
|
315
|
+
|
316
|
+
initVector = generate_initialization_vector(block_size() / 4)
|
317
|
+
chain = encrypt_block(initVector)
|
318
|
+
cryptStream.write(chain)
|
319
|
+
|
320
|
+
while ((block = plainStream.read(block_size())) && (block.length == block_size()))
|
321
|
+
block = block ^ chain
|
322
|
+
encrypted = encrypt_block(block)
|
323
|
+
cryptStream.write(encrypted)
|
324
|
+
chain = encrypted
|
191
325
|
end
|
192
326
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
327
|
+
# write the final block
|
328
|
+
# At most block_size()-1 bytes can be part of the message.
|
329
|
+
# That means the final byte can be used to store the number of meaningful
|
330
|
+
# bytes in the final block
|
331
|
+
block = '' if block.nil?
|
332
|
+
buffer = block.split('')
|
333
|
+
remainingMessageBytes = buffer.length
|
334
|
+
# we use 7-bit characters to avoid possible strange behavior on the Mac
|
335
|
+
remainingMessageBytes.upto(block_size()-2) { buffer << rand(128).chr }
|
336
|
+
buffer << remainingMessageBytes.chr
|
337
|
+
block = buffer.join('')
|
338
|
+
block = block ^ chain
|
339
|
+
encrypted = encrypt_block(block)
|
340
|
+
cryptStream.write(encrypted)
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
def decrypt_stream(cryptStream, plainStream)
|
345
|
+
# Cypher-block-chain mode
|
346
|
+
chain = cryptStream.read(block_size())
|
347
|
+
|
348
|
+
while (block = cryptStream.read(block_size()))
|
349
|
+
decrypted = decrypt_block(block)
|
350
|
+
plainText = decrypted ^ chain
|
351
|
+
plainStream.write(plainText) unless cryptStream.eof?
|
352
|
+
chain = block
|
203
353
|
end
|
204
354
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
355
|
+
# write the final block, omitting the padding
|
356
|
+
buffer = plainText.split('')
|
357
|
+
remainingMessageBytes = buffer.last.unpack('C').first
|
358
|
+
remainingMessageBytes.times { plainStream.write(buffer.shift) }
|
359
|
+
end
|
360
|
+
|
361
|
+
|
362
|
+
def carefully_open_file(filename, mode)
|
363
|
+
begin
|
364
|
+
aFile = File.new(filename, mode)
|
365
|
+
rescue
|
366
|
+
puts "Sorry. There was a problem opening the file <#{filename}>."
|
367
|
+
aFile.close() unless aFile.nil?
|
368
|
+
raise
|
209
369
|
end
|
370
|
+
return(aFile)
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
def encrypt_file(plainFilename, cryptFilename)
|
375
|
+
plainFile = carefully_open_file(plainFilename, 'rb')
|
376
|
+
cryptFile = carefully_open_file(cryptFilename, 'wb+')
|
377
|
+
encrypt_stream(plainFile, cryptFile)
|
378
|
+
plainFile.close unless plainFile.closed?
|
379
|
+
cryptFile.close unless cryptFile.closed?
|
380
|
+
end
|
381
|
+
|
210
382
|
|
383
|
+
def decrypt_file(cryptFilename, plainFilename)
|
384
|
+
cryptFile = carefully_open_file(cryptFilename, 'rb')
|
385
|
+
plainFile = carefully_open_file(plainFilename, 'wb+')
|
386
|
+
decrypt_stream(cryptFile, plainFile)
|
387
|
+
cryptFile.close unless cryptFile.closed?
|
388
|
+
plainFile.close unless plainFile.closed?
|
211
389
|
end
|
212
390
|
|
213
|
-
=end
|
214
391
|
|
392
|
+
def encrypt_string(plainText)
|
393
|
+
plainStream = StringIO.new(plainText)
|
394
|
+
cryptStream = StringIO.new('')
|
395
|
+
encrypt_stream(plainStream, cryptStream)
|
396
|
+
cryptText = cryptStream.string
|
397
|
+
return(cryptText)
|
398
|
+
end
|
399
|
+
|
400
|
+
|
401
|
+
def decrypt_string(cryptText)
|
402
|
+
cryptStream = StringIO.new(cryptText)
|
403
|
+
plainStream = StringIO.new('')
|
404
|
+
decrypt_stream(cryptStream, plainStream)
|
405
|
+
plainText = plainStream.string
|
406
|
+
return(plainText)
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
|
412
|
+
class String
|
413
|
+
|
414
|
+
def ^(aString)
|
415
|
+
a = self.unpack('C'*(self.length))
|
416
|
+
b = aString.unpack('C'*(aString.length))
|
417
|
+
if (b.length < a.length)
|
418
|
+
(a.length - b.length).times { b << 0 }
|
419
|
+
end
|
420
|
+
xor = ""
|
421
|
+
0.upto(a.length-1) { |pos|
|
422
|
+
x = a[pos] ^ b[pos]
|
423
|
+
xor << x.chr()
|
424
|
+
}
|
425
|
+
return(xor)
|
426
|
+
end
|
427
|
+
|
428
|
+
end
|
data/lib/more/facets/ziputils.rb
CHANGED
@@ -140,7 +140,7 @@ module ZipUtils
|
|
140
140
|
raise ArgumentError if folder == '.*'
|
141
141
|
# name of file to create
|
142
142
|
file ||= File.basename(File.expand_path(folder)) + '.zip'
|
143
|
-
cmd = "zip -
|
143
|
+
cmd = "zip -rqu #{file} #{folder}"
|
144
144
|
# display equivalent commandline
|
145
145
|
if options[:verbose] or options[:dryrun]
|
146
146
|
puts cmd
|
data/log/changelog.txt
ADDED
File without changes
|
data/log/history.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
= Facets Revision History
|
2
|
+
|
3
|
+
== 2.1.0 / 2007-11-10
|
4
|
+
|
5
|
+
* Major Changes
|
6
|
+
* command.rb has been completely rewritten. The API has changed completely!
|
7
|
+
* There is no longer a Commmand::Optoins class. Use Console::Arguments instead.
|
8
|
+
* Added BiCrypt class to crypt.rb for simple two-way encyrption.
|
9
|
+
* Minor Changes
|
10
|
+
* module/attr.rb now has attr_reader!, attr_writer! and attr_accessor!
|
11
|
+
* All attr_xxx methods have coresponding alias_xxx methods.
|
12
|
+
* Fixed bug in Enumerable#cluster_by which returned nil instead of [].
|
13
|
+
|
14
|
+
== 2.0.5 / 2007-11-07
|
15
|
+
|
16
|
+
* Major Changes
|
17
|
+
* Added final methods Gavin Sinclair's Extensions project (contributed by Noah Gibbs).
|
18
|
+
* Minor Changes
|
19
|
+
* Fixes bug with Dictionary#initialize
|
20
|
+
* Fixes bug with Hash#-
|
21
|
+
* Also improves changelog production.
|
22
|
+
|
data/log/release.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
== 2.1.0 / 2007-11-10
|
2
|
+
|
3
|
+
* Major Changes
|
4
|
+
* command.rb has been completely rewritten. The API has changed completely!
|
5
|
+
* There is no longer a Commmand::Optoins class. Use Console::Arguments instead.
|
6
|
+
* Added BiCrypt class to crypt.rb for simple two-way encyrption.
|
7
|
+
* Minor Changes
|
8
|
+
* module/attr.rb now has attr_reader!, attr_writer! and attr_accessor!
|
9
|
+
* All attr_xxx methods have coresponding alias_xxx methods.
|
10
|
+
* Fixed bug in Enumerable#cluster_by which returned nil instead of [].
|
data/log/todo.txt
ADDED
File without changes
|
data/meta/google_ad.html
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
<div style="position: absolute; top: 5px; right: 10px;">
|
2
|
+
<script type="text/javascript"><!--
|
3
|
+
google_ad_client = "pub-1126154564663472";
|
4
|
+
google_ad_width = 234;
|
5
|
+
google_ad_height = 60;
|
6
|
+
google_ad_format = "234x60_as";
|
7
|
+
google_ad_type = "text_image";
|
8
|
+
//2007-08-31: facets
|
9
|
+
google_ad_channel = "2923120207";
|
10
|
+
//-->
|
11
|
+
</script>
|
12
|
+
<script type="text/javascript"
|
13
|
+
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
14
|
+
</script>
|
15
|
+
</div>
|
data/meta/icli.yaml
CHANGED
data/meta/manifest.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
AUTHORS
|
3
3
|
LICENSE
|
4
4
|
README
|
5
|
-
|
5
|
+
WHATSNEW
|
6
6
|
demo
|
7
7
|
demo/bench
|
8
8
|
demo/bench/enumerable
|
@@ -463,12 +463,23 @@ lib/methods/facets/module
|
|
463
463
|
lib/methods/facets/module/alias_accessor.rb
|
464
464
|
lib/methods/facets/module/alias_method_chain.rb
|
465
465
|
lib/methods/facets/module/alias_module_function.rb
|
466
|
+
lib/methods/facets/module/alias_reader.rb
|
467
|
+
lib/methods/facets/module/alias_setter.rb
|
468
|
+
lib/methods/facets/module/alias_switcher.rb
|
469
|
+
lib/methods/facets/module/alias_tester.rb
|
470
|
+
lib/methods/facets/module/alias_toggler.rb
|
471
|
+
lib/methods/facets/module/alias_validator.rb
|
472
|
+
lib/methods/facets/module/alias_writer.rb
|
466
473
|
lib/methods/facets/module/all_instance_methods.rb
|
467
474
|
lib/methods/facets/module/ancestor.rb
|
475
|
+
lib/methods/facets/module/attr_accessor.rb
|
476
|
+
lib/methods/facets/module/attr_reader.rb
|
468
477
|
lib/methods/facets/module/attr_setter.rb
|
478
|
+
lib/methods/facets/module/attr_switcher.rb
|
469
479
|
lib/methods/facets/module/attr_tester.rb
|
470
480
|
lib/methods/facets/module/attr_toggler.rb
|
471
481
|
lib/methods/facets/module/attr_validator.rb
|
482
|
+
lib/methods/facets/module/attr_writer.rb
|
472
483
|
lib/methods/facets/module/basename.rb
|
473
484
|
lib/methods/facets/module/by_name.rb
|
474
485
|
lib/methods/facets/module/can.rb
|
@@ -726,12 +737,20 @@ lib/more/facets/uploadutils.rb
|
|
726
737
|
lib/more/facets/version.rb
|
727
738
|
lib/more/facets/yaml.rb
|
728
739
|
lib/more/facets/ziputils.rb
|
740
|
+
log
|
741
|
+
log/changelog.txt
|
742
|
+
log/history.txt
|
743
|
+
log/release.txt
|
744
|
+
log/todo.txt
|
729
745
|
meta
|
730
|
-
meta/facets-2.0.
|
746
|
+
meta/facets-2.1.0.roll
|
747
|
+
meta/google_ad.html
|
731
748
|
meta/icli.yaml
|
732
749
|
meta/manifest.txt
|
733
750
|
task
|
734
751
|
task/clean
|
752
|
+
task/clobber
|
753
|
+
task/clobber/package
|
735
754
|
task/config
|
736
755
|
task/config/general.yaml
|
737
756
|
task/config/rdoc.yaml
|
@@ -745,6 +764,9 @@ task/methods
|
|
745
764
|
task/prepare
|
746
765
|
task/publish
|
747
766
|
task/rdoc
|
767
|
+
task/release
|
768
|
+
task/special
|
769
|
+
task/special/quickopts
|
748
770
|
task/stats
|
749
771
|
task/syntax
|
750
772
|
task/test
|
@@ -886,7 +908,6 @@ test/unit/test_buildingblock.rb
|
|
886
908
|
test/unit/test_bytes.rb
|
887
909
|
test/unit/test_class_extension.rb
|
888
910
|
test/unit/test_classmethods.rb
|
889
|
-
test/unit/test_command.rb
|
890
911
|
test/unit/test_compare_on.rb
|
891
912
|
test/unit/test_conversion.rb
|
892
913
|
test/unit/test_coroutine.rb
|