Class: Digest::ED2k
- Inherits:
-
Class
- Object
- Class
- Digest::ED2k
- Defined in:
- lib/digest/ed2k.rb
Overview
Due to ed2k’s use of 9500KB chunks, this object can be up to around 10MB large in memory, not counting OpenSSL::Digest::MD4’s state.
Digest subclass that calculates an ed2k hash.
The implemented algorithm is as described on wiki.anidb.net/w/Ed2k, using the “red code” method (appending null to hashlist).
Uses OpenSSL::Digest::MD4 internally for the MD4 hashing.
Constant Summary collapse
- VERSION =
The version
'1.0.0'
- CHUNK_SIZE =
Chunk size of the ed2k hash, 9500KB.
9728000
Class Method Summary collapse
-
.digest(data) ⇒ Object
Calculates and returns the #digest on data.
-
.file(path) ⇒ Object
The same as calling #file(path) on a new object.
-
.hexdigest(data) ⇒ Object
Calculates and returns the #hexdigest on data.
-
.io(io) ⇒ Object
The same as calling #io(io) on a new object.
Instance Method Summary collapse
-
#digest(str = nil) ⇒ String
#finalizes the digest and returns it.
-
#digest! ⇒ String
#finalizes the digest and returns it.
-
#file(path) ⇒ Object
Opens the file pointed by path and calls #io with it.
-
#finalize ⇒ Object
Finalizes the digest and prevents any new data from being added to it.
-
#hexdigest(str = nil) ⇒ String
-
#hexdigest! ⇒ String
-
#initialize(initial_chunk = nil) ⇒ ED2k
constructor
Creates a reset object.
-
#inspect ⇒ Object
Override for Object’s inspect.
-
#io(io) ⇒ Object
Reads the contents of ‘io`, 9500KB at a time, until EOF, and add to the digest.
-
#reset ⇒ Object
Resets the state; effectively the same as constructing a new object.
-
#update(data) ⇒ Object
(also: #<<)
Append ‘data` to the digest.
Constructor Details
#initialize(initial_chunk = nil) ⇒ ED2k
Creates a reset object.
26 27 28 29 30 |
# File 'lib/digest/ed2k.rb', line 26 def initialize (initial_chunk = nil) @md4 = OpenSSL::Digest::MD4.new self.reset self << initial_chunk if initial_chunk end |
Class Method Details
.digest(data) ⇒ Object
Calculates and returns the #digest on data.
175 176 177 |
# File 'lib/digest/ed2k.rb', line 175 def self.digest (data) return new(data).digest end |
.file(path) ⇒ Object
The same as calling #file(path) on a new object.
190 191 192 |
# File 'lib/digest/ed2k.rb', line 190 def self.file(path) return new.file path end |
.hexdigest(data) ⇒ Object
Calculates and returns the #hexdigest on data.
180 181 182 |
# File 'lib/digest/ed2k.rb', line 180 def self.hexdigest (data) return new(data).hexdigest end |
.io(io) ⇒ Object
The same as calling #io(io) on a new object.
185 186 187 |
# File 'lib/digest/ed2k.rb', line 185 def self.io(io) return new.io io end |
Instance Method Details
#digest(str = nil) ⇒ String
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/digest/ed2k.rb', line 92 def digest(str = nil) unless str self.finalize @md4.digest else reset self << str digest end end |
#digest! ⇒ String
105 106 107 108 109 |
# File 'lib/digest/ed2k.rb', line 105 def digest! ret = digest reset return ret end |
#file(path) ⇒ Object
Opens the file pointed by path and calls #io with it.
50 51 52 53 54 |
# File 'lib/digest/ed2k.rb', line 50 def file (path) File.open(path) do |f| return self.io f end end |
#finalize ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/digest/ed2k.rb', line 141 def finalize unless @finalized if @rounds > 0 @md4 << OpenSSL::Digest::MD4.digest(@buf) else @md4.reset @md4 << @buf end @buf = nil @finalized = true end return self end |
#hexdigest(str = nil) ⇒ String
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/digest/ed2k.rb', line 115 def hexdigest(str = nil) unless str self.finalize @md4.hexdigest else reset self << str hexdigest end end |
#hexdigest! ⇒ String
130 131 132 133 134 |
# File 'lib/digest/ed2k.rb', line 130 def hexdigest! ret = hexdigest reset return ret end |
#inspect ⇒ Object
Override for Object’s inspect
156 157 158 159 |
# File 'lib/digest/ed2k.rb', line 156 def inspect return "#<ed2k unfinalized>" unless @finalized return "#<ed2k hash=\"#{digest}\">" end |
#io(io) ⇒ Object
Reads the contents of ‘io`, 9500KB at a time, until EOF, and add to the digest.
37 38 39 40 41 42 43 44 |
# File 'lib/digest/ed2k.rb', line 37 def io (io) # why do I have to use a while instead of an each_chunk or sth buf = "" while io.read CHUNK_SIZE, buf self << buf end return self end |
#reset ⇒ Object
Resets the state; effectively the same as constructing a new object.
58 59 60 61 62 63 64 |
# File 'lib/digest/ed2k.rb', line 58 def reset @md4.reset @buf = "" @rounds = 0 @finalized = false return self end |
#update(data) ⇒ Object Also known as: <<
Append ‘data` to the digest. Will raise an ArgumentError if the object has been #finalized before.
Every 9500KB of accumulated data will be hashed as per the ed2k algorithm.
73 74 75 76 77 78 79 80 |
# File 'lib/digest/ed2k.rb', line 73 def update (data) if @finalized raise ArgumentError.new("Can't add to an ed2k hash after finalizing. Call reset if you want to calculate a new hash.") end @buf += data _sync return self end |