189

I'm looking for the best way to create a unique ID as a String in Java.

Any guidance appreciated, thanks.

I should mention I'm using Java 5.

Supertux
  • 7,198
  • 10
  • 39
  • 46

11 Answers11

390

Create a UUID.

String uniqueID = UUID.randomUUID().toString();
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
aperkins
  • 12,114
  • 4
  • 26
  • 32
  • 6
    It's not *all* that human readable tho... – pjp Sep 07 '09 at 14:56
  • 14
    @pjp: a truely randomly generated ID usually isn't human-readable. And making it human-readable usually makes it longer which in turn makes it less human-readable. – Joachim Sauer Sep 07 '09 at 14:58
  • 7
    I wasn't aware he wanted a human readable unique ID ... that would increase the difficulty quite a bit – aperkins Sep 07 '09 at 15:03
  • 1
    Another note - if you only need application uniqueness, and AtomicInteger (as noted by Michael Borgwardt) is a much better option, but if you need global uniqueness, a UUID is a much better bet. – aperkins Sep 07 '09 at 15:19
  • 1
    Why can't we use `System.currentTimeMillis` to generate a monotonically increasing sequence and add some random positive integer salt? – Farhad Aug 02 '16 at 10:06
  • You certainly can @Farhad, but the UUID is about the only way to guarantee uniqueness across multiple servers with large traffic volume. – aperkins Aug 03 '16 at 15:41
53

If you want short, human-readable IDs and only need them to be unique per JVM run:

private static long idCounter = 0;

public static synchronized String createID()
{
    return String.valueOf(idCounter++);
}    

Edit: Alternative suggested in the comments - this relies on under-the-hood "magic" for thread safety, but is more scalable and just as safe:

private static AtomicLong idCounter = new AtomicLong();

public static String createID()
{
    return String.valueOf(idCounter.getAndIncrement());
}
Michael Borgwardt
  • 327,225
  • 74
  • 458
  • 699
  • 1
    I prefer Michael's method to the UUID approach as sequential IDs are more typically useful / easier when debugging. Also, UUID.randomUUID() isn't 100% guaranteed to return a unique value. – Adamski Sep 07 '09 at 15:03
  • 13
    @Adamski: this method will only create unique values as long as you don't restart the JVM, have only 1 JVM running and as long as the counter doesn't overflow. All those assumptions can easily be broken. UUID.randomUUID() is actually more reliable in those situations. – Joachim Sauer Sep 07 '09 at 15:18
  • 2
    While it is not 100% guaranteed, the odds are so low of you colliding with anyone (as the entire space is larger than the number of atoms estimated to exist in the Universe) as to be 100% guaranteed. And if you need global uniqueness, it is the easiest way to achieve that. However, if you only need local uniqueness (i.e. to a current existing application) then AtomicInteger is definitely the way to go. – aperkins Sep 07 '09 at 15:20
23

java.util.UUID : toString() method

Mitch Wheat
  • 280,588
  • 41
  • 444
  • 526
19

Here's my two cent's worth: I've previously implemented an IdFactory class that created IDs in the format [host name]-[application start time]-[current time]-[discriminator]. This largely guaranteed that IDs were unique across JVM instances whilst keeping the IDs readable (albeit quite long). Here's the code in case it's of any use:

public class IdFactoryImpl implements IdFactory {
  private final String hostName;
  private final long creationTimeMillis;
  private long lastTimeMillis;
  private long discriminator;

  public IdFactoryImpl() throws UnknownHostException {
    this.hostName = InetAddress.getLocalHost().getHostAddress();
    this.creationTimeMillis = System.currentTimeMillis();
    this.lastTimeMillis = creationTimeMillis;
  }

  public synchronized Serializable createId() {
    String id;
    long now = System.currentTimeMillis();

    if (now == lastTimeMillis) {
      ++discriminator;
    } else {
      discriminator = 0;
    }

    // creationTimeMillis used to prevent multiple instances of the JVM
    // running on the same host returning clashing IDs.
    // The only way a clash could occur is if the applications started at
    // exactly the same time.
    id = String.format("%s-%d-%d-%d", hostName, creationTimeMillis, now, discriminator);
    lastTimeMillis = now;

    return id;
  }

  public static void main(String[] args) throws UnknownHostException {
    IdFactory fact = new IdFactoryImpl();

    for (int i=0; i<1000; ++i) {
      System.err.println(fact.createId());
    }
  }
}
Adamski
  • 51,827
  • 12
  • 103
  • 150
9

Generate Unique ID Using Java

UUID is the fastest and easiest way to generate unique ID in Java.

import java.util.UUID;

public class UniqueIDTest {
  public static void main(String[] args) {
    UUID uniqueKey = UUID.randomUUID();
    System.out.println (uniqueKey);
  }
}
UdayKiran Pulipati
  • 6,053
  • 7
  • 60
  • 84
8

IMHO aperkins provided an an elegant solution cause is native and use less code. But if you need a shorter ID you can use this approach to reduce the generated String length:

// usage: GenerateShortUUID.next();
import java.util.UUID;

public class GenerateShortUUID() {

  private GenerateShortUUID() { } // singleton

  public static String next() {
     UUID u = UUID.randomUUID();
     return toIDString(u.getMostSignificantBits()) + toIDString(u.getLeastSignificantBits());
  }

  private static String toIDString(long i) {
      char[] buf = new char[32];
      int z = 64; // 1 << 6;
      int cp = 32;
      long b = z - 1;
      do {
          buf[--cp] = DIGITS66[(int)(i & b)];
          i >>>= 6;
      } while (i != 0);
      return new String(buf, cp, (32-cp));
  }

 // array de 64+2 digitos 
 private final static char[] DIGITS66 = {
    '0','1','2','3','4','5','6','7','8','9',        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
    '-','.','_','~'
  };

}
rharari
  • 171
  • 2
  • 4
8

This adds a bit more randomness to the UUID generation but ensures each generated id is the same length

import org.apache.commons.codec.digest.DigestUtils;
import java.util.UUID;

public String createSalt() {
    String ts = String.valueOf(System.currentTimeMillis());
    String rand = UUID.randomUUID().toString();
    return DigestUtils.sha1Hex(ts + rand);
}
Robert Alderson
  • 105
  • 1
  • 1
  • 1
    I liked the additional currentTimeMillis which really makes this random. – Mercury Apr 20 '17 at 21:16
  • 9
    UUID.randomUUID() already generates ids using "cryptographically strong" random number generator. What does it mean to add 'a bit more randomness'? What do you get by attaching a random 'salt' based on epoch time? – Dan May 10 '18 at 19:07
  • 1
    if I remember correctly `UUID.randomUUID()` already uses time factor while creating random ID. – Paramvir Singh Karwal Feb 23 '19 at 17:09
2

We can create a unique ID in java by using the UUID and call the method like randomUUID() on UUID.

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

This will generate the random uniqueID whose return type will be String.

simhumileco
  • 21,911
  • 14
  • 106
  • 90
Prabhat
  • 21
  • 2
1

There are three way to generate unique id in java.

1) the UUID class provides a simple means for generating unique ids.

 UUID id = UUID.randomUUID();
 System.out.println(id);

2) SecureRandom and MessageDigest

//initialization of the application
 SecureRandom prng = SecureRandom.getInstance("SHA1PRNG");

//generate a random number
 String randomNum = new Integer(prng.nextInt()).toString();

//get its digest
 MessageDigest sha = MessageDigest.getInstance("SHA-1");
 byte[] result =  sha.digest(randomNum.getBytes());

System.out.println("Random number: " + randomNum);
System.out.println("Message digest: " + new String(result));

3) using a java.rmi.server.UID

UID userId = new UID();
System.out.println("userId: " + userId);
Md Ayub Ali Sarker
  • 7,364
  • 2
  • 19
  • 18
1

Unique ID with count information

import java.util.concurrent.atomic.AtomicLong;

public class RandomIdUtils {

    private static AtomicLong atomicCounter = new AtomicLong();

    public static String createId() {

        String currentCounter = String.valueOf(atomicCounter.getAndIncrement());
        String uniqueId = UUID.randomUUID().toString();

        return uniqueId + "-" + currentCounter;
    }
}
simhumileco
  • 21,911
  • 14
  • 106
  • 90
1
String name,password;

public int idGen() {

    int id = this.name.hashCode() + this.password.hashCode();
    int length = String.valueOf(id).length();
    int Max_Length = 5;
    if(String.valueOf(id).length()>Max_Length) 
    {
        id = (int) (id /Math.pow(10.0,length - Max_Length ));
    }
    return  id;
}
Hatim
  • 11
  • 1