删除随机生成的 UUID 中的“-”有多安全?

How safe is it to remove the "-" in a randomly generated UUID?

我有这个代码:

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

删除生成的 UUID 中的“-”是否安全?删除它是否会破坏它的全局唯一性并使生成的 UUID 容易发生冲突?

how safe if is to remove the "-" in the generated UUID

它是 100% 安全的,因为破折号不是值的一部分。字符串 UUID 是 128 位值的十六进制表示。破折号只是为了显示目的,所以 UUID 在眼睛上会更容易一些。

String 形式的 UUID 传递给外部系统(例如外部 API、数据库和类似性质的东西)时要小心。他们可能希望破折号在那里。

UUID 是一个 128 位数字。

带连字符的十六进制格式仅供人类使用的显示效果图。它是几种可能的显示渲染之一,显示格式(带或不带连字符)不是 UUID 本身。

您可以通过阅读 the javadoc:

来检查字符串是如何创建的
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 对象。

关于唯一性:How unique is UUID?

格式正确的 UUID 中的破折号不会随机放置在字符串中 - 它是 RFC 中详述的特定格式 - http://www.ietf.org/rfc/rfc4122.txt

因此,删除破折号不会影响 UUID 的唯一性。

但是,它可能会导致一些库出现问题,这些库希望破折号作为 UUID 的一部分来验证它是 UUID。

为什么要删除它们?

假设我想给白宫打电话。他们的 phone 号码是 (202) 456-1111。如果我从那个 phone 数字中删除所有破折号和括号,我剩下 2024561111。在执行此操作的过程中我没有丢失任何信息 - 我只是以一种使其更难的方式更改了格式阅读。如果我将这个号码打入我的 ​​phone,它仍然会正常拨打电话,因为 phone 系统仍然知道前三位数字是区号,接下来的七位是总机号码。

以同样的方式,UUID 中的破折号就像 phone 数字中的额外标点符号 - 它们包含在内是为了让人们更容易阅读一些潜在的大数字。在 UUID 中,该数字为 128 位长,并以十六进制表示,因此与 phone 数字不同,它不是“明显”的数字,但基本原理是相同的。删除破折号不会更改数字,因此不会影响安全性。

现在,可能发生的是这样做会破坏跨平台的格式兼容性。让我们回到 phone 数字类比。我用过的一些网站不允许我输入 2024561111 作为 phone 数字。他们会坚持让我在 (202) 456-1111 中加入空格、破折号和括号。 (我不喜欢这样的网站,但那是另一回事了。)因此,如果您需要将 UUID 的字符串表示形式传递到其他需要完整格式,包括逗号。

UUID 是一个 128 位数字。数字M的四位表示UUID版本,数字N的高一到三位表示UUID变体。 UUID 的二进制编码因系统而异。许多系统完全以大端格式对 UUID 进行编码。