Reputation: 2876
I want to generate time-based universally unique identifier (UUID) in Java.
The method java.util.UUID.randomUUID()
generates a UUID Version 4 where 122 of the 128 bits are from a cryptographically-strong random number generator.
How to generate a Version 1 (time based) UUID ? Is there a separate library for that or is it some how provided in the Java 7 API and I am missing it.
Upvotes: 82
Views: 109722
Reputation: 338266
Version 1 UUIDs actually represent a point in space and in time.
The "space" part is the MAC address taken from the networking port of the computer to uniquely identify where the id was generated (nearly unique, there have been some infamous screw-ups in assigning MAC addresses by the networking hardware manufacturers).
The "time" part is a 60-bit timestamp, being the number of 100-nanosecond intervals since midnight 15 October 1582 Coordinated Universal Time (UTC).
As you have noticed, no implementation of Version 1 UUID is required by the Java specifications.
Presumably this is because of the security and privacy concerns from potentially divulging your MAC address and the moment of creation.
As seen on the other Answers, there are 3rd-party implementations of Version 1 UUIDs available.
Asking for library recommendations is off-topic here on Stack Overflow. So I asked on the sister site, Software Recommendations Stack Exchange, the question Library to generate Version 1 UUIDs to be called from Java.
And here is a condensed list of the implementations mentioned in other Answers here and elsewhere that seem to still be actively supported.
TimeUUID
or UUIDGen
class source code, part of the Apache Cassandra project. This source code is published under the Apache 2 license.FYI, work has been underway in recent years to define new versions of UUID. The most critically important is Version 6, rearranging the date-time bits to make them friendlier to database indexing.
Upvotes: 17
Reputation: 1197
Here is another way to generate time-based UUIDs using the open-source project UUID Creator:
UUID uuid = UuidCreator.getTimeBased();
This library can also generate time-ordered UUIDs, aka UUID v6.
UUID v6, v7, & v8 are proposed additions to RFC 4122. The draft is being discussed in a GitHub repository.
See the articles here and here to understand the reason for new UUIDs.
An implementation of v6 can be found on that same UUID Creator library. See this exemple:
UUID uuid = UuidCreator.getTimeOrdered();
Disclaimer: I'm the main contributor of uuid-creator
.
Upvotes: 9
Reputation: 32315
If you aren't interested in integrating Yet Another Java Library™️, here's a bit of Java code to generate Version 1 UUIDs. Home brew, so YMMV.
Pre-conditions:
// fake clock_sequence and node_id
var rng = SecureRandom.getInstanceStrong();
short clock_sequence = (short) rng.nextInt(0x10000);
byte[] node = new byte[6];
rng.nextBytes(node);
Instant time = Instant.now(); // if you don't want "now", pick something else
var dur = Duration.between(ZonedDateTime.of(1582, 10, 15, 0, 0, 0, 0,
ZoneOffset.UTC), // RFC-specified epoch, no idea why
time.atZone(ZoneOffset.UTC));
var timestamp = dur.getSeconds() * 10000 + dur.getNano() / 100;
var time_low = timestamp & 0xFFFFFFFFL;
timestamp >>>= 32;
var time_mid = timestamp & 0xFFFFL;
timestamp >>>= 16;
var time_high_and_ver = timestamp & 0xFFF | (1 << 12); // add version 1
var msb = time_low << 32 | time_mid << 16 | time_high_and_ver;
ByteBuffer data = ByteBuffer.allocate(8);
data.putShort(clock_sequence & 0x3FFF | 0x8000); // add RFC variant
data.put(node);
data.flip();
var lsb = data.getLong();
// compose the UUID
return new java.util.UUID(msb, lsb);
The full implementation is also available, MIT licensed, for download at https://github.com/guss77/java-uuid
Upvotes: 1
Reputation: 31
To generate time based UUIDs in maven project you have add the dependency of Generator that is generate time based UUIDs.
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>3.1.4</version>
</dependency>
If you have a normal java project you have to import library of Generator java-uuid-generator.
Then generate the UUID:
UUID uuid= Generators.timeBasedGenerator().generate();
Now if you want to check the UUID time and date check here.
Enter generated UUID and your current time zone.
Upvotes: 1
Reputation: 4566
Cassandra's implementation or in Github of type 1 UUID: usage Do note that you do not compare these uuids like uuid1>uuid2 etc because of known bug
Upvotes: 1
Reputation: 39
To test our application, we have to generate data which has time-based UUID, using com.eaio.uuid.UUID we generated old time stamp UUIDs and hence were able to control the timestamp as per our test cases. Note: - We cannot generate future timestamp UUID
We generated in below way -
import com.eaio.uuid.UUID;
import com.eaio.uuid.UUIDGen;
long time = DateUtil.getEpochtimeFromDate("21-06-2018 12:30:31", "dd-M-yyy hh:hh:ss");
UUID time_based_uuid = new UUID(UUIDGen.createTime(time), UUIDGen.getClockSeqAndNode());
Upvotes: 2
Reputation: 26160
FasterXML Java Uuid Generator (JUG)
https://github.com/cowtowncoder/java-uuid-generator
UUID uuid = Generators.timeBasedGenerator().generate();
Upvotes: 18
Reputation: 498
String timeuuid = com.datastax.driver.core.utils.UUIDs.timeBased().toString();
have a look at https://docs.datastax.com/en/drivers/java/2.0/com/datastax/driver/core/utils/UUIDs.html
Upvotes: 14
Reputation: 101
Be very careful using com.eaio.uuid.UUID, if you need to generate GUID by time other than current time, as this will always generate the same UUID for given time. So if your data has requirement to generate UUID, where records may have same time, this will generate same UUID.
We needed this to generate UUID for records, which are created ahead and also multiple records at same time, we tried to tweak it by trying to use UUIDGen.createTime(). We found that it has a side effect to mutate the time for records out of order. If a subsequent request to create UUID
has a time stamp older than previous request, you end up having a UUID
, which is based on previous request's time stamp.
After all the analysis, we had to simply go back to create UUID
at the time of creation, so that we don't have to pass it as an argument. Whichever solution we come up with to generate UUID
at a later time, every one has a drawback.
Upvotes: 10