在JAVA中生成UUID字符串的有效方法(UUID.randomUUID().toString(),不带破折号)

Max*_*ler 133 java random uuid http

我想要一个有效的实用程序来生成唯一的字节序列.UUID是一个很好的候选者,但只要你不需要通过HTTP传输它就会UUID.randomUUID().toString()生成类似的东西44e128a5-ac7a-4c9a-be4c-224b6bf81b20,在这种情况下需要删除破折号.

我正在寻找一种有效的方法来生成随机字符串,仅使用字母数字字符(无破折号或任何其他特殊符号).

Ste*_*eod 240

这样做:

public static void main(String[] args) {
    final String uuid = UUID.randomUUID().toString().replace("-", "");
    System.out.println("uuid = " + uuid);
}
Run Code Online (Sandbox Code Playgroud)

  • 无需使用正则表达式的replaceAll.做.replace(" - ","") (18认同)

Don*_*onz 28

您可以在此线程的URL中看到,不需要从HTTP请求中删除虚线.但是,如果要在不依赖数据的情况下准备格式良好的URL,则应使用URLEncoder.encode(字符串数据,字符串编码),而不是更改数据的标准格式.对于UUID字符串表示,破折号是正常的.

  • 并不是说url是UUID,而是它有破折号:`http://stackoverflow.com/questions/3804591/efficient-method-to-generate-uuid-string-in-java-uuid-randomuuid-tostring-w ?rq=1` (2认同)

小智 11

我使用JUG(Java UUID Generator)生成唯一ID.它在JVM中是独一无二的.非常好用.以下是供您参考的代码:

private static final SecureRandom secureRandom = new SecureRandom();
private static final UUIDGenerator generator = UUIDGenerator.getInstance();

public synchronized static String generateUniqueId() {
  UUID uuid = generator.generateRandomBasedUUID(secureRandom);

  return uuid.toString().replaceAll("-", "").toUpperCase();
}
Run Code Online (Sandbox Code Playgroud)

您可以从以下网址下载该库:https://github.com/cowtowncoder/java-uuid-generator


Max*_*ler 11

根据UUID.java实现结束编写自己的东西.请注意,我没有生成UUID,而是以我能想到的最有效的方式生成一个随机的32字节十六进制字符串.

履行

import java.security.SecureRandom;
import java.util.UUID;

public class RandomUtil {
    // Maxim: Copied from UUID implementation :)
    private static volatile SecureRandom numberGenerator = null;
    private static final long MSB = 0x8000000000000000L;

    public static String unique() {
        SecureRandom ng = numberGenerator;
        if (ng == null) {
            numberGenerator = ng = new SecureRandom();
        }

        return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
    }       
}
Run Code Online (Sandbox Code Playgroud)

用法

RandomUtil.unique()
Run Code Online (Sandbox Code Playgroud)

测试

我测试过的一些输入以确保它正常工作:

public static void main(String[] args) {
    System.out.println(UUID.randomUUID().toString());
    System.out.println(RandomUtil.unique());

    System.out.println();
    System.out.println(Long.toHexString(0x8000000000000000L |21));
    System.out.println(Long.toBinaryString(0x8000000000000000L |21));
    System.out.println(Long.toHexString(Long.MAX_VALUE + 1));
}
Run Code Online (Sandbox Code Playgroud)


小智 7

我很惊讶看到很多字符串替换UUID的想法.这个怎么样:

UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
     + Long.toHexString(temp.getLeastSignificantBits());
Run Code Online (Sandbox Code Playgroud)

这是禁止的方式,因为UUID的整个toString()已经更加昂贵,更不用说必须被解析和执行的正则表达式或用空字符串替换.

  • `String.format("0x%016x%016x",f.getMostSignificantBits(),f.getLeastSignificantBits())` (6认同)
  • 这不可靠.如果前导位为0,则输出将更短. (5认同)

Phi*_*ßen 6

一个简单的解决方案是

UUID.randomUUID().toString().replace("-", "")
Run Code Online (Sandbox Code Playgroud)

(与现有解决方案一样,只是避免了String#replaceAll调用。此处不需要进行正则表达式替换,因此String#replace感觉更自然,尽管从技术上讲,它仍是使用正则表达式实现的。鉴于UUID的生成是比替换产品更昂贵,运行时间不应有明显差异。)

在大多数情况下,使用UUID类可能足够快,尽管我希望某些不需要后期处理的专业手写变体更快。无论如何,总体计算的瓶颈通常是随机数生成器。对于UUID类,它使用SecureRandom

使用哪个随机数生成器也是一个折衷方案,具体取决于应用程序。如果对安全性敏感,通常建议使用SecureRandom。否则,可以选择ThreadLocalRandom(比SecureRandom或旧的Random快,但不是加密安全的)。


Rav*_*sai 6

我刚刚复制了 UUID toString() 方法并更新了它以从中删除“-”。它将比任何其他解决方案更快、更直接

public String generateUUIDString(UUID uuid) {
    return (digits(uuid.getMostSignificantBits() >> 32, 8) +
            digits(uuid.getMostSignificantBits() >> 16, 4) +
            digits(uuid.getMostSignificantBits(), 4) +
            digits(uuid.getLeastSignificantBits() >> 48, 4) +
            digits(uuid.getLeastSignificantBits(), 12));
}

/** Returns val represented by the specified number of hex digits. */
private String digits(long val, int digits) {
    long hi = 1L << (digits * 4);
    return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
Run Code Online (Sandbox Code Playgroud)

用法:

generateUUIDString(UUID.randomUUID())

另一种使用反射的实现

public String generateString(UUID uuid) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    if (uuid == null) {
        return "";
    }

    Method digits = UUID.class.getDeclaredMethod("digits", long.class, int.class);
    digits.setAccessible(true);

    return ( (String) digits.invoke(uuid, uuid.getMostSignificantBits() >> 32, 8) +
            digits.invoke(uuid, uuid.getMostSignificantBits() >> 16, 4) +
            digits.invoke(uuid, uuid.getMostSignificantBits(), 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits() >> 48, 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits(), 12));

}
Run Code Online (Sandbox Code Playgroud)