我刚刚注意到#hash每次启动Ruby时更改的返回值:
$ 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
Run Code Online (Sandbox Code Playgroud)
我查看了MRI源,看看为什么会发生这种情况:
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;
}
Run Code Online (Sandbox Code Playgroud)
事实证明rb_memhash,定义random.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
}
Run Code Online (Sandbox Code Playgroud)
虽然我找不到什么ruby_sip_hash24,但我认为它不是一个确定性的功能.
经过一番混乱之后,我设法发现Tanaka Akira的这个提交由于"避免算法复杂性攻击"而改变rb_str_hash使用rb_memhash.那是什么意思?
谢谢!
| 归档时间: |
|
| 查看次数: |
194 次 |
| 最近记录: |