Creating an md5 hash of a number, string, array, or hash in Ruby

前端 未结 5 1648
轻奢々
轻奢々 2021-02-01 13:13

I need to create a signature string for a variable in Ruby, where the variable can be a number, a string, a hash, or an array. The hash values and array elements can also be any

5条回答
  •  盖世英雄少女心
    2021-02-01 14:16

    Here's my solution. I walk the data structure and build up a list of pieces that get joined into a single string. In order to ensure that the class types seen affect the hash, I inject a single unicode character that encodes basic type information along the way. (For example, we want ["1", "2", "3"].objsum != [1,2,3].objsum)

    I did this as a refinement on Object, it's easily ported to a monkey patch. To use it just require the file and run "using ObjSum".

    module ObjSum
      refine Object do
        def objsum
          parts = []
          queue = [self]
    
          while queue.size > 0
            item = queue.shift
    
            if item.kind_of?(Hash)
              parts << "\\000"
              item.keys.sort.each do |k| 
                queue << k
                queue << item[k]
              end
            elsif item.kind_of?(Set)
              parts << "\\001"
              item.to_a.sort.each { |i| queue << i }
            elsif item.kind_of?(Enumerable)
              parts << "\\002"
              item.each { |i| queue << i }
            elsif item.kind_of?(Fixnum)
              parts << "\\003"
              parts << item.to_s
            elsif item.kind_of?(Float)
              parts << "\\004"
              parts << item.to_s
            else
              parts << item.to_s
            end
          end
    
          Digest::MD5.hexdigest(parts.join)
        end
      end
    end
    

提交回复
热议问题