是否有一种快速简便的方法从Ruby的基本数据结构创建校验和?

Hub*_*bro 7 ruby hash checksum

我有一个Hash看起来像这样的数据结构():

{
    foo: "Test string",
    bar: [475934759, 5619827847]
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个校验和,Hash以检查将来是否相等.我尝试使用它的hash方法Hash,这导致了一个令人满意的好看的哈希,但事实证明,在Hash重新启动解释器后,相同的将产生不同的哈希.

我真的希望能够从创建〜128位的校验和Hash,StringArray实例.

这可能吗?

Ste*_*fan 6

您可以根据对象的Marshal转储JSON表示来计算自己的哈希值.

这会计算Marshal转储的MD5哈希值:

require 'digest/md5'

hash = {
  foo: "Test string",
  bar: [475934759, 5619827847]
}

Marshal::dump(hash)
#=> "\x04\b{\a:\bfooI\"\x10Test string\x06:\x06ET:\bbar[\ai\x04'0^\x1Cl+\b\x87\xC4\xF7N\x01\x00"

Digest::MD5.hexdigest(Marshal::dump(hash))
#=> "1b6308abdd8f5f6290e2825a078a1a02"
Run Code Online (Sandbox Code Playgroud)

更新

您可以实施自己的策略,但我不建议更改核心功能:

class Hash
  def _dump(depth)
    # this doesn't cause a recursion because sort returns an array
    Marshal::dump(self.sort, depth)
  end

  def self._load(marshaled_hash)
    Hash[Marshal::load(marshaled_hash)]
  end
end

Marshal::dump({foo:1, bar:2})
#=> "\x04\bu:\tHash\e\x04\b[\a[\a:\bbari\a[\a:\bfooi\x06"

Marshal::dump({bar:2, foo:1})
#=> "\x04\bu:\tHash\e\x04\b[\a[\a:\bbari\a[\a:\bfooi\x06"

Marshal::load(Marshal::dump({foo:1, bar:2}))
#=> {:bar=>2, :foo=>1}
Run Code Online (Sandbox Code Playgroud)

  • 这几乎就是我正在寻找的东西.我看到的唯一问题是`{foo:"bar",meow:123}`和`{meow:123,foo:"bar"}`会产生不同的哈希值,即使我认为它们是相同的.关于如何应对的任何想法? (3认同)