我需要一个四字符的哈希值。目前我正在使用md5()
哈希函数的前四个字符。我要哈希的字符串长度不超过80个字符。这样会导致冲突吗?或者,假设我将少于65,536(164)个不同元素进行哈希,冲突的可能性是多少?
我需要一个四字符的哈希值。目前我正在使用md5()
哈希函数的前四个字符。我要哈希的字符串长度不超过80个字符。这样会导致冲突吗?或者,假设我将少于65,536(164)个不同元素进行哈希,冲突的可能性是多少?
md5
的每个字符都是一个十六进制位。这意味着它可以有16种可能的值。因此,如果您只使用前4个“十六进制位”,那么您可以有16 * 16 * 16 * 16
或16^4
或65536或2^16
种可能性。50%
的机会 -> 300
条目1%
的机会 -> 36
条目0.0000001%
的机会 -> 2
条目。16^4
(65,536)个可能值的4个十六进制位26^4
(456,976)个可能值的4个字母位36^4
(1,679,616)个可能值的4个字母数字位93^4
(74,805,201)个可能值的4个可打印ASCII位(假设ASCII 33 -> 126)256^4
(4,294,967,296)个可能值的4个完整字节。$hash = substr(md5($data), 0, 4);
4个α位:
$hash = substr(base_convert(md5($data), 16, 26)0, 4);
$hash = str_replace(range(0, 9), range('S', 'Z'), $hash);
4个字母和数字位:
$hash = substr(base_convert(md5($data), 16, 36), 0, 4);
4可打印ASCII位:
$hash = hash('md5', $data, true); // We want the raw bytes
$out = '';
for ($i = 0; $i < 4; $i++) {
$out .= chr((ord($hash[$i]) % 93) + 33);
}
四个完整字节:
$hash = substr(hash('md5', $data, true), 0, 4); // We want the raw bytes
真的很高。 从这张近似碰撞概率图(公式来自wikipedia页面)中可以看出,只有几百个元素,你发生碰撞的概率就超过了50%。
当然,如果你面临攻击者提供字符串的可能性,那么你可能可以假定碰撞的概率为100%——在16位搜索空间中查找碰撞几乎可以立即在任何现代计算机上完成。甚至是任何现代手机都可以。
前4个字符包含了16位数据,因此碰撞肯定会在65536个元素处发生,并且由于生日攻击,它会被更快地发现。您应该使用更多位的哈希。