随机生成的UUID中删除"-"符号安全吗?

81

我有这段代码:

String uuid = UUID.randomUUID().toString().replace("-", "");

去掉生成的UUID中的“-”符号是否安全?去掉它会否破坏其全球唯一性并使生成的UUID容易发生碰撞?


66
UUID是一个128位的数字。短横线只是用于人类阅读显示格式的一部分,不是UUID本身的一部分。 - Jim Garrison
9
由于-符号总是出现在同样的位置,所以这是安全的。请参阅维基百科上的UUID格式 - Andreas
4
当使用版本4的UUID时,它是几乎唯一的。这意味着即使创建大量的UUID,重复的可能性也非常低。然而,由于UUID的长度只有128位,因此在极端情况下,会出现重复的情况。 - shmosel
3
你为什么想要去掉连字符?这似乎是一个相当奇怪的请求。 - Marie
3
同时,我投了反对票,因为这个问题缺乏基础研究。快速查看一下生成的几个UUID就可以迅速发现它们总是在同一个位置,并且了解什么是UUID以及它们的格式会同样很快地揭示这一点。在发布问题之前,请自行进行更多的研究并澄清自己对所使用技术的理解。请参考此链接(https://meta.stackoverflow.com/a/261593/1394393)。 - jpmc26
@Marie 我以前从UUID中移除了连字符,因为在URL中没有连字符看起来好多了 - jpmc26
6个回答

130

如果删除生成的UUID中的“-”,会有多安全?

非常安全,因为破折号不是值的一部分。字符串UUID是128位值的十六进制表示。这些破折号只是为了显示方便,使UUID看起来更加友好。

但在将UUID以String形式传递给外部系统(如外部API、数据库等)时,请注意小心。它们可能希望破折号存在。


我已经删除了有关唯一性的单独问题,因为在一个帖子中发布多个问题是被禁止的。您可能希望更新您的答案。 - jpmc26

55
假设我想拨打白宫电话,他们的电话号码是(202) 456-1111。如果我从这个电话号码中删除所有破折号和括号,剩下的是2024561111。在这个过程中,我没有丢失任何信息——我只是改变了格式,使其更难阅读。如果我在手机上拨打这个号码,它仍然可以正确地拨打电话,因为电话系统仍然知道前三个数字是区号,接下来的七个数字是主要号码。
同样,UUID中的破折号就像电话号码中的额外标点符号一样——它们被包含在内是为了让人类更容易读取一些底层的大数。在UUID中,这个数字是128位长,并用十六进制写成,所以与电话号码不同,它不太“明显”是一个数字,但基本原理相同。删除破折号不会改变该数字,因此也不会影响安全性。

现在,可能发生的情况是这样做会破坏跨平台的格式兼容性。让我们回到电话号码的比喻上。我使用过的一些网站不会让我将2024561111输入为电话号码,他们坚持要我加入空格、破折号和括号,如(202) 456-1111。(我不喜欢这样的网站,但那是另一个故事了。)因此,如果您需要将UUID的字符串表示形式传递给某个其他需要包括逗号在内的完整格式的进程或服务,则从UUID中删除连字符可能会成为问题。


12
正确格式的UUID中的破折号不是随机放置在字符串中的 - 这是RFC中详细说明的特定格式 - http://www.ietf.org/rfc/rfc4122.txt 因此,移除破折号不会影响UUID的唯一性。
但是,这可能会导致使用破折号作为UUID的一部分进行验证的库出现问题。
你为什么想要删除它们?

9

您可以通过阅读Java文档来查看字符串是如何创建的:

UUID                   = <time_low> "-" <time_mid> "-"
                      <time_high_and_version> "-"
                      <variant_and_sequence> "-"
                      <node>
time_low               = 4*<hexOctet>
time_mid               = 2*<hexOctet>
time_high_and_version  = 2*<hexOctet>
variant_and_sequence   = 2*<hexOctet>
node                   = 6*<hexOctet>

去掉-是可以的,如果需要的话,你可以在正确的位置重新插入它们,或者创建一个包含相同信息的UUID对象。

关于唯一性:UUID有多独特?


8

UUID是一个128位的数字。

十六进制格式中带有连字符仅用于人类消费的显示呈现。这是几种可能的显示呈现之一,显示格式是否带有连字符不影响UUID本身。


1
UUID是一个128位的数字。数字M的四个比特表示UUID版本,数字N的一到三个最高有效比特表示UUID变体。UUID的二进制编码在不同的系统中有所不同。许多系统将UUID完全以大端格式进行编码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接