为什么Ruby #hash方法是随机的?

时间:2014-04-28 02:45:59

标签: ruby

我刚注意到每次启动Ruby时#hash的返回值都会发生变化:

$ irb
2.0.0-p353 :001 > "".hash
2313425349783613115
2.0.0-p353 :002 > exit

$ irb
2.0.0-p353 :001 > "".hash
4543564897974813688
2.0.0-p353 :002 > exit

我看了核磁共振源,看看为什么会发生这种情况:

st_index_t
rb_str_hash(VALUE str)
{
    int e = ENCODING_GET(str);
    if (e && rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
    e = 0;
    }
    return rb_memhash((const void *)RSTRING_PTR(str), RSTRING_LEN(str)) ^ e;
}

结果rb_memhashrandom.c中定义:

st_index_t
rb_memhash(const void *ptr, long len)
{
    sip_uint64_t h = sip_hash24(sipseed.key, ptr, len);
#ifdef HAVE_UINT64_T
    return (st_index_t)h;
#else
    return (st_index_t)(h.u32[0] ^ h.u32[1]);
#endif
}

虽然我找不到ruby_sip_hash24是什么,但我认为它不是确定性函数。

经过一番混乱之后,我设法找到了Tanaka Akira的this commit,由于“避免算法复杂性攻击”而将rb_str_hash更改为使用rb_memhash。这是什么意思?

谢谢!

1 个答案:

答案 0 :(得分:6)

正如提交消息所述,它应该避免 algorithmic complexity attacks

  

算法复杂性攻击是一种计算机攻击形式   利用在一个软件中使用的算法的已知情况   将表现出最坏的情况。可以使用这种类型的攻击   实现拒绝服务

通过使用rb_memhash,每次启动新的ruby执行上下文时,哈希结果都将被随机化。否则,如果没有随机化,攻击者就会知道算法,并且可以找出可能用作 DoS 攻击的最坏情况行为。