我想要一个高效的实用程序来生成唯一的字节序列。UUID是一个很好的候选人,但会UUID.randomUUID().toString()
生成类似的东西44e128a5-ac7a-4c9a-be4c-224b6bf81b20
,但我更喜欢无破折号的字符串。
我正在寻找一种仅从字母数字字符(无破折号或任何其他特殊符号)生成随机字符串的有效方法。
我想要一个高效的实用程序来生成唯一的字节序列。UUID是一个很好的候选人,但会UUID.randomUUID().toString()
生成类似的东西44e128a5-ac7a-4c9a-be4c-224b6bf81b20
,但我更喜欢无破折号的字符串。
我正在寻找一种仅从字母数字字符(无破折号或任何其他特殊符号)生成随机字符串的有效方法。
Answers:
这样做:
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString().replace("-", "");
System.out.println("uuid = " + uuid);
}
正如您在该线程的URL中看到的那样,不需要从HTTP请求中删除短划线。但是,如果您要准备格式正确的URL,而不依赖数据,则应使用URLEncoder.encode(String data,String encoding)而不是更改数据的标准格式。对于UUID字符串,破折号是正常的。
http://stackoverflow.com/questions/3804591/efficient-method-to-generate-uuid-string-in-java-uuid-randomuuid-tostring-w?rq=1
最终基于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());
}
}
RandomUtil.unique()
我测试了一些输入以确保其正常工作:
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));
}
我使用JUG(Java UUID生成器)生成唯一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();
}
您可以从以下网址下载该库:https : //github.com/cowtowncoder/java-uuid-generator
java.util.UUID
选择。
一个简单的解决方案是
UUID.randomUUID().toString().replace("-", "")
(与现有解决方案一样,只是避免了String#replaceAll调用。此处不需要进行正则表达式替换,因此String#replace感觉更自然,尽管从技术上讲,它仍是使用正则表达式实现的。鉴于UUID的生成是比替换产品更昂贵,运行时间不应有明显差异。)
在大多数情况下,使用UUID类可能足够快,尽管我希望某些不需要后期处理的专用手写变体更快。无论如何,总体计算的瓶颈通常是随机数生成器。对于UUID类,它使用SecureRandom。
使用哪个随机数发生器也是一个折衷方案,具体取决于应用程序。如果对安全性敏感,通常建议使用SecureRandom。否则,可以选择ThreadLocalRandom(比SecureRandom或旧的Random快,但不是加密安全的)。
我很惊讶地看到如此多的UUID字符串替换想法。这个怎么样:
UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
+ Long.toHexString(temp.getLeastSignificantBits());
这是执行此操作的快速方法,因为整个UUID的toString()已经更昂贵了,更不用说必须解析和执行的正则表达式,或者用空字符串替换。
String.format("0x%016x%016x", f.getMostSignificantBits(), f.getLeastSignificantBits())
replace
?
我刚刚复制了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);
}
用法:
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));
}
我使用org.apache.commons.codec.binary.Base64将UUID转换为长度为22个字符且具有与UUID相同的唯一性的URL安全唯一字符串。
我在将UUID存储为base64字符串时发布了代码