如果我多次运行以下单行ruby脚本,则每次都会产生不同的输出值。
puts "This is a string".hash
这是怎么回事?对于任何给定的输入字符串,我应该如何更改它以使其从.hash获得一致,可重现的值?
编辑:“可能重复”建议其他哈希方法。我正在尝试重现另一个我无法控制使用.hash并获得一致结果的脚本的行为。不能更改哈希方法。
编辑#2:如下面的另一条注释所述,我要重现其行为的另一个脚本位于.exe包装器内。它可以追溯到2006年,这意味着Ruby版本必须为1.8.5或更早版本。 #hash方法在Ruby早期版本中的工作方式是否有所不同,如果是,是否有人生产了可复制那些早期版本行为的脚本? (可以使用其他名称。)
答案 0 :(得分:3)
这是怎么回事?
#hash
对于不同的对象应该是不同的,对于相等的对象,在程序的生存期内应该相同。绝对不能保证程序不同调用之间的值是什么。
The documentation在这里非常明确(粗体是我的重点):
对象的哈希值在调用之间或Ruby的实现中可能不相同。如果您需要跨Ruby调用和实现的稳定标识符,则需要使用自定义方法生成一个标识符。
[注意:由于某些原因,Ruby的当前版本的文档未在ruby-doc.org上正确呈现。 It is identical in the current master branch, though.]
对于任何给定的输入字符串,我应该如何更改它以使其从.hash获得一致,可重现的值?
不使用它。
答案 1 :(得分:0)
我认为了解#hash
的含义可能会有所帮助。它用于将Ruby对象存储到Hash
数据结构的特定存储区中-或,或者将其包含在Set
中-但这是一个实现细节,因为Ruby Set是在Hash的“顶部”实现的。它不用于摘要值。一旦知道,#hash
显然不应该满足以下约束:
它应满足以下约束条件
st_index_t
的大小)可以通过多种方式满足第二个要求。例如,可以通过使用更快的哈希函数来满足要求。但是,也可以通过查找“任意”计算得出的哈希值来满足此要求,例如查找字符串,以及如果此特定字符串是另一个字符串的重复-通过重用该值。另一种方法(有时也应用)是从Ruby对象ID导出哈希值,该哈希值根据定义在虚拟机的运行中发生变化。
所以Jörg所说的确实如此-出于您的目的,hash()函数不是一个很好的选择,因为它是为不同的用例而设计的。但是,还有很多替代方法-常用的SHA,杂项哈希,xxhash等-可能会满足您的要求并保证是基于内容的。