Efficient method to generate UUID String in Java (UUID.randomUUID().toString() without the dashes)
Solution 1
Ended up writing something of my own based on UUID.java implementation. Note that I'm not generating a UUID, instead just a random 32 bytes hex string in the most efficient way I could think of.
Implementation
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());
}
}
Usage
RandomUtil.unique()
Tests
Some of the inputs I've tested to make sure it's working:
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));
}
Solution 2
This does it:
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString().replace("-", "");
System.out.println("uuid = " + uuid);
}
Solution 3
Dashes don't need to be removed from HTTP request as you can see in URL of this thread. But if you want to prepare well-formed URL without dependency on data you should use URLEncoder.encode( String data, String encoding ) instead of changing standard form of you data. For UUID string representation dashes is normal.
Solution 4
I used JUG (Java UUID Generator) to generate unique ID. It is unique across JVMs. Pretty good to use. Here is the code for your reference:
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();
}
You could download the library from: https://github.com/cowtowncoder/java-uuid-generator
Solution 5
A simple solution is
UUID.randomUUID().toString().replace("-", "")
(Like the existing solutions, only that it avoids the String#replaceAll call. Regular expression replacement is not required here, so String#replace feels more natural, though technically it still is implemented with regular expressions. Given that the generation of the UUID is more costly than the replacement, there should not be a significant difference in runtime.)
Using the UUID class is probably fast enough for most scenarios, though I would expect that some specialized hand-written variant, which does not need the postprocessing, to be faster. Anyway, the bottleneck of the overall computation will normally be the random number generator. In case of the UUID class, it uses SecureRandom.
Which random number generator to use is also a trade-off that depends on the application. If it is security-sensitive, SecureRandom is, in general, the recommendation. Otherwise, ThreadLocalRandom is an alternative (faster than SecureRandom or the old Random, but not cryptographically secure).
Comments
-
Maxim Veksler almost 2 years
I would like an efficient utility to generate unique sequences of bytes. UUID is a good candidate but
UUID.randomUUID().toString()
generates stuff like44e128a5-ac7a-4c9a-be4c-224b6bf81b20
which is good, but I would prefer dash-less string.I'm looking for an efficient way to generate a random strings, only from alphanumeric characters (no dashes or any other special symbols).
-
Bruno over 13 yearsWhy do the dashes need to be removed for such a UUID to be transmitted over HTTP?
-
Jon Skeet over 13 yearsI didn't think dashes needed to be removed in HTTP in general... which bit is causing you hassle?
-
Guido over 13 yearsMaybe in a mobile environment, if you still pay for each byte transmitted, and using a low-bandwidth & high-latency network, saving 4 bytes is still important in some scenarios...
-
Maxim Veksler over 13 yearsI want the dashes to be removed because we later using the UUID string as unique request identifier, it's much easier working with only hex decimal chars then [a-f0-9-].
-
febot over 4 yearsI have removed the HTTP part because it's not relevant (as Maxim explained), only confuses the readers (as can be seen both in comments and answers).
-
-
Maxim Veksler over 13 yearsFor your case what's wrong with UUID.randomUUID().toString() ? Also note that you (theoretically) decrease the entropy by holding a static final SecureRandom (make it volatile). also why synchronize the generateUniqueId? This means all your threads are blocked on this method.
-
Sheng Chien over 13 yearsFirst of all, Safehaus claims JUG is faster. And it can generate unique IDs across machines which you might not need. They have time-based method which is the fatest one among all methods. Yes, synchronized is not necessary here cause' I realized SecureRandom is thread safe already. Why would declaring static final on SecureRandom would decrease the entropy? I am curious :) There are more details here: jug.safehaus.org/FAQ
-
StaxMan over 13 yearsJUG can generate random-number based UUIDs as well; but the main reasons why developers prefer using time-based variant is either that it's 10-20x faster (cowtowncoder.com/blog/archives/2010/10/entry_429.html); or that they don't trust randomness to produce unique ids (which is kinda funny)
-
Daniel Serodio over 11 yearsjug.safehaus.org doesn't exist anymore, but you can find the FAQ at raw.github.com/cowtowncoder/java-uuid-generator/3.0/…
-
RenniePet over 9 years"Dashes don't need to be removed from HTTP request as you can see in URL of this thread." Don't understand, unless Stack Overflow previously used UUIDs in their URLs?
-
Octavia Togami over 9 yearsNot that the url is a UUID, but that it has dashes:
http://stackoverflow.com/questions/3804591/efficient-method-to-generate-uuid-string-in-java-uuid-randomuuid-tostring-w?rq=1
-
Alexey Ryazhskikh about 9 yearsFor example, Mongodb do not uses dashes in ObjectID. So removing dashes can be useful for api.
-
Greg Dubicki over 8 years+1 for mentioning JUG - I have review its usefulness but it's good to know that there are some serious
java.util.UUID
alternatives. -
Michael Gaines over 8 yearsI'll give you a reason why. There's an API I'm working with (high profile, well known) that doesn't allow dashes in its UUID. You have to strip them.
-
Craigo almost 8 yearsNo need to do replaceAll, that uses regular expressions. Just do .replace("-", "")
-
OG Dude almost 8 yearsThis is not reliable. The output will be shorter if leading bits are 0.
-
Maxim Veksler over 7 yearsnot sure why this is upvoted more, this generated UUID without the "-" in the most efficient method from all the options written here. String replacement is not better then conversion from long to string. It's true that both are O(n), yet at scale where you generate millions of uuid's a minute it becomes meaningful.
-
n99 over 7 years
String.format("0x%016x%016x", f.getMostSignificantBits(), f.getLeastSignificantBits())
-
igorcadelima over 6 years@galets Although I've up voted your comment for solving the issue with leading 0s, I wonder whether this would be any better compared to the alternative of replacing dashes using
replace
. -
Mike almost 5 years
-
bmscomp over 4 yearsreplace method of String class is a bit slow, I think
-
Gaurav over 4 years@bmscomp for the first invocation, it is slow, but for next invocations, there is no issue.