如何缩短使用randomUUID()生成的UUID长度

27

我有一个简短的实用程序,在其中使用randomUUID()生成UUID。

String uuid = UUID.randomUUID().toString();

然而,生成的UUID太长了,长度为36。

是否有任何方法可以将UUID的长度从36减少到接近16或使UUID的长度动态变化?


13
顺便说一下,“短UUID”不再是UUID。 - user972946
可能是生成UUID但仅限8个字符的重复问题。 - GaryF
1
避免哈希或UUID冲突与值空间的大小成正比,也与元素数量的平方成正比。将长度减少到16个随机十六进制字符很可能会失去UUID的有效唯一性保证。 - Thomas W
7个回答

37

如果您不需要它是唯一的,您可以使用任何长度。

例如,您可以这样做。

Random rand = new Random();
char[] chars = new char[16];
for(int i=0;i<chars.length;i++) {
    chars[i] = (char) rand.nextInt(65536);
    if (!Character.isValidCodePoint(chars[i]))
        i--;
}
String s = new String(chars);

这将为您提供几乎相同程度的随机性,但将使用\u0000\ufffd之间的每个可能字符。

如果您需要可打印的ASCII字符,则可以将其缩短到所需长度,但唯一性的可能性会显著降低。您可以使用基数36而不是基数16。

UUID uuid = UUID.randomUUID();
String s = Long.toString(uuid.getMostSignificantBits(), 36) + '-' + Long.toString(uuid.getLeastSignificantBits(), 36);

平均来说这将会有26个字符,最多27个字符。

您可以使用base64编码并将其缩减为22个字符。

如果您使用base94,则可以将其压缩到20个字符。

如果您使用从\u0000到\ufffd的完整有效字符范围,则只需9个字符或17个字节即可缩小它。

如果您不关心字符串,可以使用16个8位字节。


嗨,@Peter Lawrey。我想在Java中保持我的数字唯一且在整数范围内。我已根据自己的需求修改了您的代码,即UUID uuid = UUID.randomUUID(); String idString = Long.toString(uuid.getMostSignificantBits(), 36).replaceAll("-", "").replaceAll("[a-z]",""); int id; System.out.println(id = Integer.parseInt(idString)); 但是当我测试我的代码时,12个数字中有一个重复的数字。所以你能否为我提供任何可靠的解决方案? - Vibhav Chaddha

5
String uuid = String.format("%040d", new BigInteger(UUID.randomUUID().toString().replace("-", ""), 16));

String uuid16digits = uuid.substring(uuid.length() - 16);

这将返回实际 UUID 的最后 16 位数字。


2
将其从16进制(0-9,A-F)转换为36进制(0-9,A-Z)。你也可以转换为62进制(0-9, A-Z, a-z),但如果需要通过电话等方式读取,则可能会出错。https://github.com/salieri/uuid-encoder是一个可能适合您的库...
另外,这意味着您仍然拥有GUID - 您没有像其他答案那样截断它。

1
您可以使用子字符串方法来减少字符串长度,同时生成uuid。
UUID.randomUUID().toString().substring(0, 5)

0
以下代码片段是动态UUID代码。默认情况下,UUID的长度取决于位数,但该函数会随机选择UUID中的字符。
 public String myUUID(int length) {
    String allChars = UUID.randomUUID().toString().replace("-", "");
    Random random = new Random();
    char[] otp = new char[length];
    for (int i = 0; i < length; i++) {
      otp[i] =
          allChars.charAt(random.nextInt(allChars.length()));
    }
    return String.valueOf(otp);
  }

0
您可以使用${__time()}函数进行评估。

-2

是的,您可以使用此函数创建。

public static String shortUUID() {
  UUID uuid = UUID.randomUUID();
  long l = ByteBuffer.wrap(uuid.toString().getBytes()).getLong();
  return Long.toString(l, Character.MAX_RADIX);
}

2
以下是对以下答案的评论可能会有帮助:https://dev59.com/xG855IYBdhLWcg3wj1MS#17183247 - Lifeweaver

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