A Java library for generating Universally Unique Lexicographically Sortable Identifiers (ULID)
Go to file
Fabio Lima d3277fe372 Module name for Java 9+ #11
Add this line to MANIFEST.MF:

Automatic-Module-Name: com.github.f4b6a3.ulid
2021-07-17 14:02:34 -03:00
src Add static methods for extracting time and random components #9 2021-02-13 20:14:31 -03:00
.gitignore Updated pom.xml to use commons 2020-03-15 05:17:00 -03:00
CHANGELOG.md Module name for Java 9+ #11 2021-07-17 14:02:34 -03:00
LICENSE Version 2.0.0 2020-07-04 12:37:50 -03:00
README.md Module name for Java 9+ #11 2021-07-17 14:02:34 -03:00
pom.xml Module name for Java 9+ #11 2021-07-17 14:02:34 -03:00

README.md

ULID Creator

A Java library for generating ULIDs (Universally Unique Lexicographically Sortable Identifier).

  • Generated in lexicographical order;
  • Can be stored as a UUID/GUID;
  • Can be stored as a string of 26 chars;
  • Can be stored as an array of 16 bytes;
  • String format is encoded to Crockford's base32;
  • String format is URL safe and case insensitive.

How to Use

Create a ULID:

Ulid ulid = UlidCreator.getUlid();

Create a Monotonic ULID:

Ulid ulid = UlidCreator.getMonotonicUlid();

Maven dependency

Add these lines to your pom.xml.

<!-- https://search.maven.org/artifact/com.github.f4b6a3/ulid-creator -->
<dependency>
  <groupId>com.github.f4b6a3</groupId>
  <artifactId>ulid-creator</artifactId>
  <version>3.1.1</version>
</dependency>

See more options in maven.org.

Module name: com.github.f4b6a3.ulid.

ULID

The ULID is a 128 bit long identifier. The first 48 bits represent the count of milliseconds since Unix Epoch, 1970-01-01. The remaining 80 bits are generated by a secure random number generator.

// Generate a ULID
Ulid ulid = UlidCreator.getUlid();
// Generate a ULID with a specific time
Ulid ulid = UlidCreator.getUlid(1234567890);

Sequence of ULIDs:

01EX8Y21KBH49ZZCA7KSKH6X1C
01EX8Y21KBJTFK0JV5J20QPQNR
01EX8Y21KBG2CS1V6WQCTVM7K6
01EX8Y21KB8HPZNBP3PTW7HVEY
01EX8Y21KB3HZV38VAPTPAG1TY
01EX8Y21KB9FTEJHPAGAKYG9Z8
01EX8Y21KBQGKGH2SVPQAYEFFC
01EX8Y21KBY17J9WR9KQR8SE7H
01EX8Y21KCVHYSJGVK4HBXDMR9 < millisecond changed
01EX8Y21KC668W3PEDEAGDHMVG
01EX8Y21KC53D2S5ADQ2EST327
01EX8Y21KCPQ3TENMTY1S7HV56
01EX8Y21KC3755QF9STQEV05EB
01EX8Y21KC5ZSHK908GMDK69WE
01EX8Y21KCSGJS8S1FVS06B3SX
01EX8Y21KC6ZBWQ0JBV337R1CN
         ^ look

|---------|--------------|
    time      random

Monotonic ULID

The Monotonic ULID is a 128 bit long identifier. The first 48 bits represent the count of milliseconds since Unix Epoch, 1970-01-01. The remaining 80 bits are generated by a secure random number generator.

The random component is incremented by 1 whenever the current millisecond is equal to the previous one. But when the current millisecond is different, the random component changes to another random value.

// Generate a Monotonic ULID
Ulid ulid = UlidCreator.getMonotonicUlid();
// Generate a Monotonic ULID with a specific time
Ulid ulid = UlidCreator.getMonotonicUlid(1234567890);

Sequence of Monotonic ULIDs:

01EX8Y7M8MDVX3M3EQG69EEMJW
01EX8Y7M8MDVX3M3EQG69EEMJX
01EX8Y7M8MDVX3M3EQG69EEMJY
01EX8Y7M8MDVX3M3EQG69EEMJZ
01EX8Y7M8MDVX3M3EQG69EEMK0
01EX8Y7M8MDVX3M3EQG69EEMK1
01EX8Y7M8MDVX3M3EQG69EEMK2
01EX8Y7M8MDVX3M3EQG69EEMK3
01EX8Y7M8N1G30CYF2PJR23J2J < millisecond changed
01EX8Y7M8N1G30CYF2PJR23J2K
01EX8Y7M8N1G30CYF2PJR23J2M
01EX8Y7M8N1G30CYF2PJR23J2N
01EX8Y7M8N1G30CYF2PJR23J2P
01EX8Y7M8N1G30CYF2PJR23J2Q
01EX8Y7M8N1G30CYF2PJR23J2R
01EX8Y7M8N1G30CYF2PJR23J2S
         ^ look          ^ look

|---------|--------------|
    time      random

Other usage examples

Create a ULID from a canonical string (26 chars):

Ulid ulid = Ulid.from("0123456789ABCDEFGHJKMNPQRS");

Convert a ULID into a canonical string in upper case:

String string = ulid.toUpperCase(); // 0123456789ABCDEFGHJKMNPQRS

Convert a ULID into a canonical string in lower case:

String string = ulid.toLowerCase(); // 0123456789abcdefghjkmnpqrs

Convert a ULID into a UUID:

UUID uuid = ulid.toUuid(); // 0110c853-1d09-52d8-d73e-1194e95b5f19

Convert a ULID into a RFC-4122 UUID v4:

UUID uuid = ulid.toRfc4122().toUuid(); // 0110c853-1d09-42d8-973e-1194e95b5f19
                                       //               ^ UUID v4

Convert a ULID into a byte array:

byte[] bytes = ulid.toBytes(); // 16 bytes (128 bits)

Get the creation instant of a ULID:

Instant instant = ulid.getInstant(); // 2007-02-16T02:13:14.633Z
// static method
Instant instant = Ulid.getInstant("0123456789ABCDEFGHJKMNPQRS"); // 2007-02-16T02:13:14.633Z

Get the time component of a ULID:

long time = ulid.getTime(); // 1171591994633
// static method
long time = Ulid.getTime("0123456789ABCDEFGHJKMNPQRS"); // 1171591994633

Get the random component of a ULID:

byte[] random = ulid.getRandom(); // 10 bytes (80 bits)
// static method
byte[] random = Ulid.getRandom("0123456789ABCDEFGHJKMNPQRS"); // 10 bytes (80 bits)

Use a UlidFactory instance with java.util.Random to generate ULIDs:

Random random = new Random();
UlidFactory factory = UlidCreator.getDefaultFactory().withRandomGenerator(random::nextBytes);

Ulid ulid = factory.create();

Use a UlidFactory instance with any random generator you like(*) to generate ULIDs:

import com.github.niceguy.random.AwesomeRandom; // a hypothetical RNG
AwesomeRandom awesomeRandom = new AwesomeRandom();
UlidFactory factory = UlidCreator.getDefaultFactory().withRandomGenerator(awesomeRandom::nextBytes);

Ulid ulid = factory.create();

(*) as long as it provides a void method like nextBytes(byte[]).

Benchmark

This section shows benchmarks comparing UlidCreator to java.util.UUID.

================================================================================
THROUGHPUT (operations/msec)           Mode  Cnt      Score     Error   Units
================================================================================
Throughput.Uuid01_toString              thrpt    5   2876,799 ±  39,938  ops/ms
Throughput.Uuid02_fromString            thrpt    5   1936,569 ±  38,822  ops/ms
Throughput.Uuid03_RandomBased           thrpt    5   2011,774 ±  21,198  ops/ms
--------------------------------------------------------------------------------
Throughput.UlidCreator01_toString       thrpt    5  29487,382 ± 627,808  ops/ms
Throughput.UlidCreator02_fromString     thrpt    5  21194,263 ± 706,398  ops/ms
Throughput.UlidCreator03_Ulid           thrpt    5   2745,123 ±  41,326  ops/ms
Throughput.UlidCreator04_MonotonicUlid  thrpt    5  19542,344 ± 423,271  ops/ms
================================================================================
Total time: 00:09:22
================================================================================

System: JVM 8, Ubuntu 20.04, CPU i5-3330, 8G RAM.

See: uuid-creator-benchmark

Other generators