Efficient method to generate UUID String in Java (UUID.randomUUID().toString() without the dashes)

340,255

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).

Share:
340,255
Maxim Veksler
Author by

Maxim Veksler

Doing healthy things at K Health

Updated on August 06, 2022

Comments

  • Maxim Veksler
    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 like 44e128a5-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
      Bruno over 13 years
      Why do the dashes need to be removed for such a UUID to be transmitted over HTTP?
    • Jon Skeet
      Jon Skeet over 13 years
      I didn't think dashes needed to be removed in HTTP in general... which bit is causing you hassle?
    • Guido
      Guido over 13 years
      Maybe 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
      Maxim Veksler over 13 years
      I 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
      febot over 4 years
      I 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
    Maxim Veksler over 13 years
    For 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
    Sheng Chien over 13 years
    First 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
    StaxMan over 13 years
    JUG 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
    Daniel Serodio over 11 years
    jug.safehaus.org doesn't exist anymore, but you can find the FAQ at raw.github.com/cowtowncoder/java-uuid-generator/3.0/…
  • RenniePet
    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
    Octavia Togami over 9 years
    Not that the url is a UUID, but that it has dashes: http://stackoverflow.com/questions/3804591/efficient-method-‌​to-generate-uuid-str‌​ing-in-java-uuid-ran‌​domuuid-tostring-w?r‌​q=1
  • Alexey Ryazhskikh
    Alexey Ryazhskikh about 9 years
    For example, Mongodb do not uses dashes in ObjectID. So removing dashes can be useful for api.
  • Greg Dubicki
    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
    Michael Gaines over 8 years
    I'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
    Craigo almost 8 years
    No need to do replaceAll, that uses regular expressions. Just do .replace("-", "")
  • OG Dude
    OG Dude almost 8 years
    This is not reliable. The output will be shorter if leading bits are 0.
  • Maxim Veksler
    Maxim Veksler over 7 years
    not 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
    n99 over 7 years
    String.format("0x%016x%016x", f.getMostSignificantBits(), f.getLeastSignificantBits())
  • igorcadelima
    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
    Mike almost 5 years
  • bmscomp
    bmscomp over 4 years
    replace method of String class is a bit slow, I think
  • Gaurav
    Gaurav over 4 years
    @bmscomp for the first invocation, it is slow, but for next invocations, there is no issue.