建立无冲突的唯一ID

问题描述

我正在研究系统设计,并且一直在阅读URL缩短器。我意识到围绕此主题有很多问题,但是对于哈希以及哈希+编码的顺序有一些特定的问题。


输入https://example.com/owjpojwepofjwpoejfpwjepfojpwejfp/wefoijhwioejfiowef/weoifhwoiehjfiowef

输出https://example.com/abr4fna


如果我通过md5运行此输入,则会得到以下9e91e9c2a7ce0f0d11b475d2abfb8593。显然,这超出了我想要的长度,因此我可以截断(0,7]中的子字符串。问题是,在某种程度上,我仍然会发生冲突,因为md5的前缀不能保证唯一服务中生成的url数量增加

如果我以前已经使用过此ID,我不想检查数据库,因为这会使我正在执行的读取数量与正在执行的写入数量成比例。另外,随着我​​进行哈希生成和存储的应用服务器数量增加,可能会出现并发问题。

我看到有人提到使用base64编码输出哈希,但是在哈希之后这会增加什么值?是因为我将唯一组合的数量增加了64 ^ n,其中n是哈希的长度,而md5仅为36 ^ n?

谢谢。只是有兴趣进行此讨论。

编辑:

据我了解,如果接收系统在解释输出哈希值中的二进制数据时遇到问题,我们纯粹是在进行编码,以确保不会出现传输故障-因此,它纯粹是为了显示

解决方法

根据定义,您不能散列较大的域,并且期望获得较小的域而不会发生冲突。哈希是有用的,因为它是单向的,并且需要计算上不可行的尝试来找到那些冲突。但是,具有7个字符的输出和较大的输入域,即使碰巧也很容易产生碰撞。

您当前正在使用7个十六进制数字。每个十六进制数字代表4位。因此,您有28位或2 ^ 28个可能的值。可能的值约为2.56亿。因此,如果您猜足够长的时间,就会足够快地发生碰撞。使用base64时,每个字符将有6位(2 ^ 6 = 64,因此是名称)。这意味着您将位大小增加了7 * 2 = 14位,或者说是16,000倍,但是距离无冲突还差得很远。

实际上,对于采用生日界限时的任何密码保证,MD5的16字节输出大约是您要避免冲突的哈希的绝对最小大小。当然,MD5并没有被淘汰,您真的想使用SHA-256。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...