lib/dionysus/digest.rb in dionysus-0.3.0 vs lib/dionysus/digest.rb in dionysus-0.3.1

- old
+ new

@@ -63,39 +63,69 @@ end ## # The lengths of the registered digests in the given encoding. def self.digest_lengths( encoding = :binary ) - if encoding.is_a?(Symbol) - bits_per_char = case encoding - when :binary then 8 - when :base64 then 6 - when :hex, :hexidecimal then 4 - when :bit then 1 - else raise ArgumentError, "Invalid encoding" - end + if encoding == :bit or encoding == 1 + _digest_lengths(1) + elsif encoding.is_a?(Symbol) and String::ENCODING_BITS_PER_CHAR[encoding] + _digest_lengths(String::ENCODING_BITS_PER_CHAR[encoding]) elsif encoding.is_a?(Integer) and encoding > 0 - bits_per_char = encoding + _digest_lengths(encoding) else raise ArgumentError, "Invalid encoding" end - - Hash[ self.digests.collect { |dig, info| [dig, info[:bit_length] / bits_per_char] } ] end ## # Calculate the given digest of the given string. # # Examples: # # Digest.digest(:sha512, 'foobar') #=> binary digest # Digest.digest(Digest::SHA512, 'foobar') #=> binary digest - def self.digest( sym_or_klass, str ) - if sym_or_klass.is_a?(Class) - sym_or_klass - else - Digest.const_get(sym_or_klass.to_s.upcase) - end.digest(str) + def self.digest( sym, str ) + Digest.const_get(sym.to_s.upcase).digest(str) + end + + ## + # Detect the digest of the string. Returns nil if the digest cannot be + # determined. + # + # Example: + # Digest.detect_digest("wxeCFXPVXePFcpwuFDjonyn1G/w=", :base64) #=> :sha1 + # Digest.detect_digest("foobar", :hex) #=> nil + def self.detect_digest( string, encoding = :binary ) + string = string.strip unless encoding == :binary + dig = self.digest_lengths(encoding).invert[string.length] + dig = :sha256 if dig == :sha2 + dig + end + + ## + # Detect the digest of the string. Returns nil if the digest cannot be + # determined. + # + # Example: + # Digest.detect_digest!("wxeCFXPVXePFcpwuFDjonyn1G/w=", :base64) #=> :sha1 + # Digest.detect_digest!("foobar", :hex) #=> RuntimeError + def self.detect_digest!( string, encoding = :binary ) + self.detect_digest(string, encoding) or raise("Unknown digest") + end + + private + + def self._digest_lengths( bits_per_char ) # :nodoc: + padding_factor = (bits_per_char.lcm(8) / bits_per_char) + + returning result={} do + self.digests.each do |dig, info| + result[dig] = len = info[:bit_length] / bits_per_char + if (t_ = len % padding_factor) != 0 + result[dig] = len + (padding_factor - t_) + end + end + end end end # Register some default digests Digest::DEFAULT_DIGESTS.each do |dig|