class Digest::ED2K

The ED2K hashing algorithm.

Constants

CHUNK_SIZE

The ED2K chunk size (9500KB).

MD4

Shortcut to the OpenSSL MD4 class.

VERSION

The current gem version.

Public Class Methods

digest(data) click to toggle source

Calculate the digest of a string.

@param [String, IO] data the string to digest @return a finalized digest object

# File lib/digest/ed2k.rb, line 132
def digest(data)
    new.digest(data)
end
file(path) click to toggle source

Create a new digest object from a file.

@param [String] path the file to read @return a new digest object

# File lib/digest/ed2k.rb, line 156
def file(path)
    new.file(path)
end
hexdigest(data) click to toggle source

Calculate the hexdigest of a string.

@param [String, IO] data the string to digest @return a finalized digest object

# File lib/digest/ed2k.rb, line 140
def hexdigest(data)
    new.hexdigest(data)
end
io(io) click to toggle source

Create a new digest object from a IO object.

@param [IO] io the IO object to read @return a new digest object

# File lib/digest/ed2k.rb, line 148
def io(io)
    new.io(io)
end
new() click to toggle source

Create a new ED2K hash object.

@return self to allow method chaining

# File lib/digest/ed2k.rb, line 18
def initialize
    @md4 = MD4.new
    reset
end

Public Instance Methods

<<(data)
Alias for: update
digest(data = nil) click to toggle source

Finalize the hash and return the digest.

If no string is provided, the current hash is used

@param [String, IO] data hash this chunk of data

# File lib/digest/ed2k.rb, line 84
def digest(data = nil)
    if data.nil?
        finish
        @md4.digest
    else
        reset
        self << data
        digest
    end
end
file(path) click to toggle source

Calculate the hash of a file.

@param [String] path the file that will be read @return self to allow method chaining

# File lib/digest/ed2k.rb, line 35
def file(path)
    io(File.open(path))
end
finish() click to toggle source

Finalize the hash.

@return self to allow method chaining

# File lib/digest/ed2k.rb, line 114
def finish
    @finalized = true unless @finalized

    self
end
hexdigest(data = nil) click to toggle source

Finalize the hash and return the hexdigest.

If no string is provided, the current hash is used

@param [String, IO] data hash this chunk of data

# File lib/digest/ed2k.rb, line 100
def hexdigest(data = nil)
    if data.nil?
        finish
        @md4.hexdigest
    else
        reset
        self << data
        hexdigest
    end
end
inspect() click to toggle source

Shows the current state and the digest class. If the digest is finalized, it shows the hexdigest.

# File lib/digest/ed2k.rb, line 122
def inspect
    dig = @finalized ? hexdigest : 'unfinalized'
    "#<#{self.class.name}: #{dig}>"
end
io(io) click to toggle source

Hash an IO object.

@param [IO] io the IO object that will be read @return self to allow method chaining

# File lib/digest/ed2k.rb, line 27
def io(io)
    self << io
end
reset() click to toggle source

Reset to the initial state.

@return self the reset digest object

# File lib/digest/ed2k.rb, line 42
def reset
    @md4.reset
    @finalized = false

    self
end
update(data) click to toggle source

Rehash with new data.

@param [String, IO] data the chunk of data to add to the hash @return self to allow method chaining @raise RuntimeError if the digest object has been finalized

# File lib/digest/ed2k.rb, line 54
def update(data)
    raise RuntimeError if @finalized

    # get the IO object
    buf = to_io(data)

    # if the chunk is smaller than CHUNK_SIZE just return the MD4 hash
    if buf.size < CHUNK_SIZE
        @md4 << buf.read
    else
        # read chunks from the IO object and update the MD4 hash
        while (chunk = buf.read(CHUNK_SIZE))
            @md4 << MD4.digest(chunk)
        end

        # weird EDonkey bug requires multiples of CHUNK_SIZE
        # to append one additional MD4 hash
        @md4 << MD4.new.digest if multiple?(buf.size)
    end

    self
end
Also aliased as: <<

Private Instance Methods

multiple?(buf_size) click to toggle source
# File lib/digest/ed2k.rb, line 173
def multiple?(buf_size)
    (buf_size % CHUNK_SIZE).zero?
end
to_io(obj) click to toggle source
# File lib/digest/ed2k.rb, line 163
def to_io(obj)
    if obj.is_a? String
        StringIO.new(obj)
    elsif obj.is_a? IO
        obj
    else
        raise ArgumentError, "cannot hash #{obj.class.name} object"
    end
end