shredder 0.1.1 → 3.0.210928

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 79cdefe01e4a370cbeabff63ec4e641945d62b239aef721050257e0a9bcf0119
4
+ data.tar.gz: d5290e49de44088fbb83a3615cea8ee7af5781b162fe3c49d202bfbe8e9a1779
5
+ SHA512:
6
+ metadata.gz: 28b6169312efdfaed3e1cc5365b866d177d09cbea1085d12eea12e63dc61f05a4561a8ea986e8f3ddd6e8e820656340d01f4f5f1e325a59b63f47bd3cb33d7fe
7
+ data.tar.gz: ad2d383ac37cd98d80676026e9d10f8c3092e3bb5f504404938809733a1e31e9e7ab4328afd596b63f83a35b04d48212e90f327446ef047deb04dce1187645f6
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # Shredder
2
+
3
+ * [VERSION 3.0.210928](https://github.com/carlosjhr64/shredder/releases)
4
+ * [github](https://github.com/carlosjhr64/shredder)
5
+ * [rubygems](https://rubygems.org/gems/shredder)
6
+
7
+ ## DESCRIPTION:
8
+
9
+ Shred a file into file fragments, and join fragments back into a restored file.
10
+
11
+ ## INSTALL:
12
+ ```console
13
+ $ gem install shredder
14
+ ```
15
+ ## HELP:
16
+ ```console
17
+ $ shredder --help
18
+ Usage:
19
+ shredder shred [:options+] <shreds=FILENAME>+
20
+ shredder sew [:options+] <shreds=FILENAME>+
21
+ Options:
22
+ --n=INTEGER Number of shreds
23
+ Types:
24
+ FILENAME /^[[:print:]]+$/
25
+ INTEGER /^[2-9]\d*$/
26
+ # Examples:
27
+ # shredder shred file.1 file.2 < file.txt
28
+ # shredder shred --n=2 file < file.txt
29
+ # shredder sew file.1 file.2 > file.txt
30
+ # shredder shred --n=2 file > file.txt
31
+ ```
32
+ ## SYNOPSIS:
33
+
34
+ ### Library
35
+ ```ruby
36
+ require 'shredder'
37
+ ```
38
+ #### Shredder::Streams
39
+ ```ruby
40
+ require 'stringio'
41
+
42
+ sewn = StringIO.new("This is a test String: 1, 2, 3.")
43
+ sewn.string.length #=> 31
44
+ shreds = [StringIO.new, StringIO.new]
45
+
46
+ shredder = Shredder::Streams.new(sewn, shreds)
47
+ shredder.shred #=> 31
48
+
49
+ shreds[0].string
50
+ #=> "T\u0001S\u001AAT\u0016T'\e\t\u001A\u001D\u0012\f\u001D"
51
+ shreds[0].string.length #=> 16
52
+
53
+ shreds[1].string
54
+ #=> "<\u001AISA\u0011\as\u0006\a]\u0011\f\u001E\u0013"
55
+ shreds[1].string.length #=> 15
56
+
57
+ restored = StringIO.new
58
+ shreds.each{|_|_.rewind}
59
+
60
+ shredder = Shredder::Streams.new(restored, shreds)
61
+ shredder.sew #=> 31
62
+
63
+ restored.string #=> "This is a test String: 1, 2, 3."
64
+ ```
65
+ #### Shredder::Files
66
+ ```ruby
67
+ sewn = './test/sewn.txt'
68
+ shreds = './tmp/shreds'
69
+ restored = './tmp/restored.txt'
70
+
71
+ File.read(sewn).chomp #=> "This is a test file: 1, 2, 3."
72
+ File.size(sewn) #=> 30
73
+
74
+ shredder = Shredder::Files.new(sewn, shreds, 3)
75
+ shredder.shreds
76
+ #=> ["./tmp/shreds.1", "./tmp/shreds.2", "./tmp/shreds.3"]
77
+ shredder.shred #=> 30
78
+
79
+ File.read(shreds+'.1') #=> "T\u001A\u001AA\u0016F\t\u0011\u0012\u0013"
80
+ File.read(shreds+'.2') #=> "<SST\a\u000F_\u001D\u001E\u001D"
81
+ File.read(shreds+'.3') #=> "\u0001IA\u0011T\u0005\u001A\f\f$"
82
+ File.size(shreds+'.3') #=> 10
83
+
84
+ shredder = Shredder::Files.new(restored, shreds, 3)
85
+ shredder.sewn #=> "./tmp/restored.txt"
86
+ shredder.sew #=> 30
87
+ File.read(restored).chomp #=> "This is a test file: 1, 2, 3."
88
+ ```
89
+ ## LICENSE:
90
+
91
+ (The MIT License)
92
+
93
+ Copyright (c) 2021 CarlosJHR64
94
+
95
+ Permission is hereby granted, free of charge, to any person obtaining
96
+ a copy of this software and associated documentation files (the
97
+ 'Software'), to deal in the Software without restriction, including
98
+ without limitation the rights to use, copy, modify, merge, publish,
99
+ distribute, sublicense, and/or sell copies of the Software, and to
100
+ permit persons to whom the Software is furnished to do so, subject to
101
+ the following conditions:
102
+
103
+ The above copyright notice and this permission notice shall be
104
+ included in all copies or substantial portions of the Software.
105
+
106
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
107
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
108
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
109
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
110
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
111
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
112
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/shredder CHANGED
@@ -1,73 +1,51 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'help_parser'
2
3
  require 'shredder'
3
- raise "Need Shredder version ~> 0.1" if Shredder::VERSION < '0.1'
4
4
 
5
- # Command line utility
6
- class ShredderCommandLine
7
- def self.version
8
- puts Shredder::VERSION
9
- exit(0)
10
- end
11
-
12
- def self.help
13
- puts <<EOT
14
- shredder --shred sewed_file shred_file1 shred_file2... # shred a file to shreds
15
- shredder --io --shred shred_file1 shred_file2... # shred stdin to shreds
16
- shredder --sew sewed_file shred_file1 shred_file2... # sew shreds back to file
17
- shredder --io --sew shred_file1 shred_file2... # sew shreds out to stdout
18
- EOT
19
- print "VERSION: "
20
- ShredderCommandLine.version
21
- end
22
-
23
- def self.parse_argv
24
- options = ''
25
- while ARGV[0]=~/^-/ do
26
- options += ARGV.shift
27
- end
28
- ShredderCommandLine.version if options =~ /-v\b/ || options =~ /--version\b/ # need to allow verbose below.
29
- ShredderCommandLine.help if ARGV.length==0 || options =~ /-h/
30
- $verbose = (options=~/--verbose\b/)? true : false
31
- # validate
32
- raise "--sew or --shred ?" if !(options=~/--sew\b/) && !(options=~/--shred\b/)
33
- length = ARGV.length
34
- raise "Expected sew shred1 shred2 ..." if length < 2 && !(options=~/--io\b/)
35
- raise "Expected shred1 shred2..." if length < 1
36
- return options
37
- end
5
+ OPTIONS = HelpParser[Shredder::VERSION, <<HELP]
6
+ Usage:
7
+ shredder shred [:options+] <shreds=FILENAME>+
8
+ shredder sew [:options+] <shreds=FILENAME>+
9
+ Options:
10
+ --n=INTEGER \t Number of shreds
11
+ Types:
12
+ FILENAME /^[[:print:]]+$/
13
+ INTEGER /^[2-9]\\d*$/
14
+ # Examples:
15
+ # shredder shred file.1 file.2 < file.txt
16
+ # shredder shred --n=2 file < file.txt
17
+ # shredder sew file.1 file.2 > file.txt
18
+ # shredder shred --n=2 file > file.txt
19
+ HELP
20
+ HelpParser.int?(:n)
38
21
 
39
- def initialize
40
- options = ShredderCommandLine.parse_argv
41
- @shredding = (options=~/--shred/)? true : false
42
- if options=~/--io/ then
43
- if @shredding then
44
- @sew = $stdin
45
- @shreds = ARGV.map{|filename| File.open(filename,'w')} # WRITE SHREDS
46
- else
47
- @sew = $stdout
48
- @shreds = ARGV.map{|filename| File.open(filename,'r')} # READ SHREDS
49
- end
50
- else
51
- @sew = ARGV.shift
52
- @shreds = ARGV
53
- end
54
- end
55
-
56
- def execute
57
- shredder = (@sew.class == String)? Shredder::Files.new(@sew,@shreds): Shredder::Streams.new(@sew,@shreds)
58
- begin
59
- (@shredding)? shredder.shred : shredder.sew
60
- rescue StandardError
61
- $stderr.puts $!
62
- ensure
63
- @shreds.each{|filehandle| filehandle.close} if !(@sew.class == String)
64
- end
22
+ shreds = OPTIONS.shreds
23
+ count = shreds.length
24
+ if n = OPTIONS.n?
25
+ if count == 1
26
+ count = n
27
+ shreds = shreds.first
28
+ elsif count != n
29
+ $stderr.puts "shred count(#{count}) not equal to n(#{n})."
30
+ exit 64
65
31
  end
66
32
  end
33
+ unless count > 1
34
+ $stderr.puts "shred count must be at least 2"
35
+ exit 64
36
+ end
67
37
 
68
- begin
69
- ShredderCommandLine.new.execute
70
- rescue StandardError
71
- $stderr.puts $!
72
- $stderr.puts $!.backtrace if $verbose
38
+ shredder = Shredder::StdIO.new(shreds, count)
39
+ case OPTIONS[1]
40
+ when 'shred'
41
+ shredder.shred
42
+ when 'sew'
43
+ begin
44
+ shredder.sew
45
+ rescue Errno::ENOENT
46
+ # Common expected type of error,
47
+ # user tries to sew non-existing shreds.
48
+ $stderr.puts $!.message
49
+ exit 65
50
+ end
73
51
  end
@@ -1,45 +1,36 @@
1
1
  module Shredder
2
2
  class Files
3
- # this one takes filenames
4
- def initialize(sew,shreds,limit=0)
5
- @sew = sew
6
- @shreds = shreds
7
- @limit = limit
3
+ include Shredder
4
+ # this one takes filenames
5
+ def initialize(sewn, shreds=sewn, m=2, n: m)
6
+ @sewn = sewn
7
+ @shreds = shred_files(shreds, n)
8
+ raise "Need at least 2 shreds" unless @shreds.length > 1
8
9
  end
9
10
 
10
- def shred(limit=@limit)
11
- reader = File.open(@sew,'r')
12
- writers = []
13
- @shreds.each{|shred| writers.push( File.open(shred,'wb') ) }
14
-
15
- count = nil
11
+ def shred(limit=0)
12
+ reader = writers = count = nil
16
13
  begin
17
- count = Shredder.shred( reader, writers, limit )
18
- rescue Exception
19
- raise $!
14
+ reader = File.open(@sewn, 'r')
15
+ writers = @shreds.map{File.open _1, 'wb'}
16
+ count = Streams.new(reader, writers).shred(limit: limit)
20
17
  ensure
21
- writers.each{|writer| writer.close}
22
- reader.close
23
- end
24
-
18
+ writers.each{_1.close} if writers
19
+ reader.close if reader
20
+ end
25
21
  return count
26
22
  end
27
23
 
28
- def sew(limit=@limit)
29
- writer = File.open(@sew,'wb')
30
- readers = []
31
- @shreds.each{|shred| readers.push( File.open(shred,'r') ) }
32
-
33
- count = nil
24
+ def sew(limit=0)
25
+ writer = readers = count = nil
34
26
  begin
35
- count = Shredder.sew( writer, readers, limit )
36
- rescue Exception
37
- raise $!
27
+ writer = File.open(@sewn, 'wb')
28
+ readers = @shreds.map{File.open(_1, 'r')}
29
+ count = Streams.new(writer, readers).sew(limit: limit)
38
30
  ensure
39
- writer.close
40
- readers.each{|reader| reader.close}
31
+ writer.close if writer
32
+ readers.each{_1.close} if readers
41
33
  end
42
-
43
34
  return count
44
35
  end
45
36
  end
@@ -0,0 +1,40 @@
1
+ module Shredder
2
+ attr_accessor :sewn, :shreds
3
+
4
+ # note that these are streams
5
+ def shred(sewn=(@sewn or $stdin), shreds=@shreds,
6
+ writers: shreds, reader: sewn, limit: 0, xor: 0)
7
+ shreds,count = writers.length,0
8
+ while byte = reader.getbyte do
9
+ writers[count%shreds].putc(xor^(xor=byte))
10
+ count += 1 # note that 0 is skipped
11
+ break if count == limit
12
+ end
13
+ return count
14
+ end
15
+
16
+ # note that these are streams
17
+ def sew(shreds=@shreds, sewn=(@sewn or $stdout),
18
+ readers: shreds, writer: sewn, limit: 0, xor: 0)
19
+ shreds,count = readers.length,0
20
+ while byte = readers[count%shreds].getbyte do
21
+ writer.putc(xor=(byte^xor))
22
+ count += 1 # note that 0 is skipped
23
+ break if count == limit
24
+ end
25
+ return count
26
+ end
27
+
28
+ def shred_files(b=nil, m=2, basename: b, n: m)
29
+ case basename
30
+ when Array
31
+ basename
32
+ when String
33
+ (1..n).map{|i| "#{basename}.#{i}"}
34
+ when Integer
35
+ (1..basename).map{|i| "#{@sewn or 'shred'}.#{i}"}
36
+ else
37
+ raise "Expected basename Array|String|Integer"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ module Shredder
2
+ class StdIO
3
+ include Shredder
4
+ # this one takes shred filenames and uses $stdin or $stdout appropriately.
5
+ def initialize(*args)
6
+ @shreds = shred_files(*args)
7
+ end
8
+
9
+ def shred(limit=0)
10
+ writers = count = nil
11
+ begin
12
+ writers = @shreds.map{File.open _1, 'wb'}
13
+ count = Streams.new($stdin, writers).shred(limit: limit)
14
+ ensure
15
+ writers.each{_1.close} if writers
16
+ end
17
+ return count
18
+ end
19
+
20
+ def sew(limit=0)
21
+ readers = count = nil
22
+ begin
23
+ readers = @shreds.map{File.open _1, 'r'}
24
+ count = Streams.new($stdout, readers).sew(limit: limit)
25
+ ensure
26
+ readers.each{_1.close} if readers
27
+ end
28
+ return count
29
+ end
30
+ end
31
+ end
@@ -1,18 +1,10 @@
1
1
  module Shredder
2
2
  class Streams
3
+ include Shredder
3
4
  # this one takes streams
4
- def initialize(sew,shreds,limit=0)
5
- @sew = sew
5
+ def initialize(sewn, shreds)
6
+ @sewn = sewn
6
7
  @shreds = shreds
7
- @limit = limit
8
- end
9
-
10
- def shred(limit=@limit)
11
- Shredder.shred(@sew,@shreds,limit)
12
- end
13
-
14
- def sew(limit=@limit)
15
- Shredder.sew(@sew,@shreds,limit)
16
8
  end
17
9
  end
18
10
  end
data/lib/shredder.rb CHANGED
@@ -1,35 +1,9 @@
1
1
  module Shredder
2
- VERSION = '0.1.1'
3
-
4
- # note that these are streams
5
- def self.shred(reader,writers,limit=0)
6
- shreds = writers.length
7
- xor = count = 0
8
- while byte = reader.getbyte do
9
- writers[ count % shreds ].putc byte^xor
10
- xor = byte
11
- count += 1
12
- # note: will not break if limit is zero
13
- break if count == limit
14
- end
15
- return count
16
- end
17
-
18
- # note that these are streams
19
- def self.sew(writer,readers,limit=0)
20
- shreds = readers.length
21
- xor = count = 0
22
- while byte = readers[ count % shreds ].getbyte do
23
- chr = byte^xor
24
- xor = chr
25
- writer.putc chr
26
- count += 1
27
- # note: will not break if limit is zero
28
- break if count == limit
29
- end
30
- return count
31
- end
32
-
33
- autoload :Files, 'shredder/files'
34
- autoload :Streams, 'shredder/streams'
2
+ VERSION = '3.0.210928'
3
+ require 'shredder/shredder'
4
+ autoload :Streams, 'shredder/streams'
5
+ autoload :StdIO, 'shredder/stdio'
6
+ autoload :Files, 'shredder/files'
35
7
  end
8
+ # Requires:
9
+ #`ruby`
metadata CHANGED
@@ -1,73 +1,75 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: shredder
3
- version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.210928
11
5
  platform: ruby
12
- authors:
13
- - carlosjhr64@gmail.com
14
- autorequire:
6
+ authors:
7
+ - CarlosJHR64
8
+ autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: help_parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '8.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 8.0.210917
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '8.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 8.0.210917
33
+ description: 'Shred a file into file fragments, and join fragments back into a restored
34
+ file.
17
35
 
18
- date: 2011-06-21 00:00:00 Z
19
- dependencies: []
20
-
21
- description: |
22
- The idea is to disperse file shreds in separate depositories
23
- such that no one depository has the entire file.
24
- Note: These are not file segments, they're shreds.
25
-
36
+ '
26
37
  email: carlosjhr64@gmail.com
27
- executables:
38
+ executables:
28
39
  - shredder
29
40
  extensions: []
30
-
31
41
  extra_rdoc_files: []
32
-
33
- files:
34
- - ./lib/shredder/streams.rb
35
- - ./lib/shredder/files.rb
36
- - ./lib/shredder.rb
37
- - ./README.txt
42
+ files:
43
+ - README.md
38
44
  - bin/shredder
39
- homepage: https://sites.google.com/site/carlosjhr64/rubygems/shredder
40
- licenses: []
41
-
42
- post_install_message:
45
+ - lib/shredder.rb
46
+ - lib/shredder/files.rb
47
+ - lib/shredder/shredder.rb
48
+ - lib/shredder/stdio.rb
49
+ - lib/shredder/streams.rb
50
+ homepage: https://github.com/carlosjhr64/shredder
51
+ licenses:
52
+ - MIT
53
+ metadata: {}
54
+ post_install_message:
43
55
  rdoc_options: []
44
-
45
- require_paths:
56
+ require_paths:
46
57
  - lib
47
- required_ruby_version: !ruby/object:Gem::Requirement
48
- none: false
49
- requirements:
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
50
60
  - - ">="
51
- - !ruby/object:Gem::Version
52
- hash: 3
53
- segments:
54
- - 0
55
- version: "0"
56
- required_rubygems_version: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
59
65
  - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
65
- requirements: []
66
-
67
- rubyforge_project:
68
- rubygems_version: 1.8.4
69
- signing_key:
70
- specification_version: 3
71
- summary: Shred a file into file fragments, and join fragments back into a restored file.
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements:
69
+ - 'ruby: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]'
70
+ rubygems_version: 3.2.22
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Shred a file into file fragments, and join fragments back into a restored
74
+ file.
72
75
  test_files: []
73
-
data/README.txt DELETED
@@ -1,28 +0,0 @@
1
- ### SYNOPSIS ###
2
-
3
- require 'shredder'
4
-
5
- # Shreds text.txt into test.f.1, test.f.2, test.f.3
6
- Shredder::Files.new('test.txt', ['test.f.1','test.f.2','test.f.3'] ).shred
7
-
8
- # Sews test.f.1, test.f.2, test.f.3 into restored.f.txt
9
- Shredder::Files.new('restored.f.txt', ['test.f.1','test.f.2','test.f.3'] ).sew
10
-
11
- # or #
12
-
13
- # shred streams #
14
- reader = File.open('test.txt','r')
15
- writers = []; ['test.s.1','test.s.2','test.s.3'].each{|writer| writers.push(File.open(writer,'wb'))}
16
- Shredder::Streams.new(reader,writers).shred
17
- reader.close
18
- writers.each{|writer| writer.close}
19
-
20
- # sew streams
21
- writer = File.open('restored.s.txt','wb')
22
- readers = []; ['test.s.1','test.s.2','test.s.3'].each{|writer| readers.push(File.open(writer,'r'))}
23
- Shredder::Streams.new(writer,readers).sew
24
- writer.close
25
- readers.each{|reader| reader.close}
26
-
27
- # Also available, Shredder.shred( writer, readers) and Shredder.sew( reader, writers )
28
- # and a command line utility, shredder (run shredder --help for more info).