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

前端 未结 5 1789
轻奢々
轻奢々 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:17

    If you could only get a string representation of body and not have the Ruby 1.8 hash come back with different orders from one time to the other, you could reliably hash that string representation. Let's get our hands dirty with some monkey patches:

    require 'digest/md5'
    
    class Object
      def md5key
        to_s
      end
    end
    
    class Array
      def md5key
        map(&:md5key).join
      end
    end
    
    class Hash
      def md5key
        sort.map(&:md5key).join
      end
    end
    

    Now any object (of the types mentioned in the question) respond to md5key by returning a reliable key to use for creating a checksum, so:

    def createsig(o)
      Digest::MD5.hexdigest(o.md5key)
    end
    

    Example:

    body = [
      {
        'bar' => [
          345,
          "baz",
        ],
        'qux' => 7,
      },
      "foo",
      123,
    ]
    p body.md5key        # => "bar345bazqux7foo123"
    p createsig(body)    # => "3a92036374de88118faf19483fe2572e"
    

    Note: This hash representation does not encode the structure, only the concatenation of the values. Therefore ["a", "b", "c"] will hash the same as ["abc"].

提交回复
热议问题