子字符串 md5 碰撞

发布于 2024-10-11 13:08:34 字数 148 浏览 4 评论 0原文

我需要一个 4 字符的哈希值。目前我正在获取 md5() 哈希值的前 4 个字符。我正在对长度不超过 80 个字符的字符串进行哈希处理。这会导致碰撞吗?或者,假设我将散列少于 65,536 (164) 个不同元素,碰撞的可能性是多少?

I need a 4-character hash. At the moment I am taking the first 4 characters of a md5() hash. I am hashing a string which is 80 characters long or less. Will this lead to collision? or, what is the chance of collision, assuming I'll hash less than 65,536 (164) different elements?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雪落纷纷 2024-10-18 13:08:34

嗯,md5 的每个字符都是一个十六进制位。这意味着它可以具有 16 个可能值之一。因此,如果您仅使用前 4 个“十六进制位”,则意味着您可以拥有 16 * 16 * 16 * 1616^4 或 65536 或 <代码>2^16 可能性。

因此,这意味着结果的总可用“空间”只有 16 位宽。现在,根据生日攻击/问题,发生碰撞的可能性如下:

  • 50% 机会 -> 300 条目
  • 1% 机会 -> 36 条目
  • 0.0000001% 机会 -> 2 条目。

所以发生碰撞的可能性相当大。

现在,您说您需要 4 个字符的哈希值。根据具体要求,您可以执行以下操作:

  • 4 个十六进制位表示 16^4 (65,536) 个可能值
  • 4 个字母位表示 26^4 (456,976) 个可能值
  • 4 36^4 的字母数字位 (1,679,616) 可能值
  • 4 大约 93^4 (74,805,201) 可能值的 ascii 可打印位(假设 ASCII 33 -> 126)
  • 4 256^4 (4,294,967,296) 个可能值的完整字节。

现在,您选择哪个将取决于实际用例。哈希值需要传输到浏览器吗?你如何存储它,等等。

我将给出每个示例(在 PHP 中,但应该很容易翻译/看看发生了什么):

4 十六进制位

$hash = substr(md5($data), 0, 4);

4 Alpha位

$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 个可打印 Assci 位

$hash = hash('md5', $data, true); // We want the raw bytes
$out = '';
for ($i = 0; $i < 4; $i++) {
    $out .= chr((ord($hash[$i]) % 93) + 33);
}

4 个完整字节

$hash = substr(hash('md5', $data, true), 0, 4); // We want the raw bytes

Well, each character of md5 is a hex bit. That means it can have one of 16 possible values. So if you're only using the first 4 "hex-bits", that means you can have 16 * 16 * 16 * 16 or 16^4 or 65536 or 2^16 possibilities.

So, that means that the total available "space" for results is only 16 bits wide. Now, according to the Birthday Attack/Problem, there are the following chances for collision:

  • 50% chance -> 300 entries
  • 1% chance -> 36 entries
  • 0.0000001% chance -> 2 entries.

So there is quite a high chance for collisions.

Now, you say you need a 4 character hash. Depending on the exact requirements, you can do:

  • 4 hex-bits for 16^4 (65,536) possible values
  • 4 alpha bits for 26^4 (456,976) possible values
  • 4 alpha numeric bits for 36^4 (1,679,616) possible values
  • 4 ascii printable bits for about 93^4 (74,805,201) possible values (assuming ASCII 33 -> 126)
  • 4 full bytes for 256^4 (4,294,967,296) possible values.

Now, which you choose will depend on the actual use case. Does the hash need to be transmitted to a browser? How are you storing it, etc.

I'll give an example of each (In PHP, but should be easy to translate / see what's going on):

4 Hex-Bits:

$hash = substr(md5($data), 0, 4);

4 Alpha bits:

$hash = substr(base_convert(md5($data), 16, 26)0, 4);
$hash = str_replace(range(0, 9), range('S', 'Z'), $hash);

4 Alpha Numeric bits:

$hash = substr(base_convert(md5($data), 16, 36), 0, 4);

4 Printable Assci Bits:

$hash = hash('md5', $data, true); // We want the raw bytes
$out = '';
for ($i = 0; $i < 4; $i++) {
    $out .= chr((ord($hash[$i]) % 93) + 33);
}

4 full bytes:

$hash = substr(hash('md5', $data, true), 0, 4); // We want the raw bytes
难如初 2024-10-18 13:08:34

确实高得惊人。 正如您从 这张近似碰撞概率图(来自 wikipedia 的公式page),只有几百个元素,发生冲突的可能性就超过 50%。

当然,请注意,如果您面临攻击者提供字符串的可能性,您可能可以假设它是 100% - 在 16 位搜索空间中扫描以查找冲突几乎可以在任何现代 PC 上立即完成。甚至任何现代手机都可以。

Surprisingly high indeed. As you can see from this graph of an approximate collision probability (formula from the wikipedia page), with just a few hundred elements your probability of having a collision is over 50%.

Note, of course, if you're facing the possibility of an attacker providing the string, you can probably assume that it's 100% - scanning to find a collision in a 16-bit search space can be done almost instantaneously on any modern PC. Or even any modern cell phone, for that matter.

虫児飞 2024-10-18 13:08:34

前4个字符包含4*4 = 16位数据,因此碰撞肯定会在65536个元素处,并且由于生日攻击,会更快地被发现。您应该使用更多的哈希值。

4 first characters contains 4*4 = 16 bits of data, so collision will be definitely at 65536 elements, and, due to birthday attack, it will be found much faster. You should use more bits of hash.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文