A Java library for generating Universally Unique Lexicographically Sortable Identifiers (ULID)
Go to file
Fabio Lima 1bee3ba042 Optimization of the ULID string validation
It's not needed to parse the whole ULID timestamp. All is needed is to
check the first two bits. They are extra bits added by the base-32
encoding. Both bits must be ZERO.
2020-11-09 04:27:20 -03:00
src Optimization of the ULID string validation 2020-11-09 04:27:20 -03:00
.gitignore Updated pom.xml to use commons 2020-03-15 05:17:00 -03:00
LICENSE Version 2.0.0 2020-07-04 12:37:50 -03:00
README.md Optimization of the ULID string validation 2020-11-09 04:27:20 -03:00
pom.xml [maven-release-plugin] prepare for next development iteration 2020-11-08 17:42:05 -03:00

README.md

ULID Creator

A Java library for generating ULIDs.

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

How to Use

Create a ULID:

UUID ulid = UlidCreator.getUlid(); // 01706d6c-6aad-c795-370c-98d0be881bba

Create a ULID string:

String ulid = UlidCreator.getUlidString(); // 01E1PPRTMSQ34W7JR5YSND6B8Z

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>2.3.2</version>
</dependency>

See more options in maven.org.

Implementation

ULID

The GUIDs in this library are based on the ULID specification. The first 48 bits represent the count of milliseconds since Unix Epoch, 1 January 1970. The remaining 60 bits are generated by a secure random number generator.

Every time the timestamp changes the random part is reset to a new random value. If the current timestamp is equal to the previous one, the random bits are incremented by 1.

The default random number generator is java.security.SecureRandom.

// GUID based on ULID spec
UUID ulid = UlidCreator.getUlid();
// GUID based on ULID spec
// Compatible with RFC-4122 UUID v4
UUID ulid = UlidCreator.getUlid4();

Sequence of GUIDs based on ULID spec:

01706d6c-6aac-80bd-7ff5-f660c2dd58ea
01706d6c-6aac-80bd-7ff5-f660c2dd58eb
01706d6c-6aac-80bd-7ff5-f660c2dd58ec
01706d6c-6aac-80bd-7ff5-f660c2dd58ed
01706d6c-6aac-80bd-7ff5-f660c2dd58ee
01706d6c-6aac-80bd-7ff5-f660c2dd58ef
01706d6c-6aac-80bd-7ff5-f660c2dd58f0
01706d6c-6aac-80bd-7ff5-f660c2dd58f1
01706d6c-6aad-c795-370c-98d0be881bb8 < millisecond changed
01706d6c-6aad-c795-370c-98d0be881bb9
01706d6c-6aad-c795-370c-98d0be881bba
01706d6c-6aad-c795-370c-98d0be881bbb
01706d6c-6aad-c795-370c-98d0be881bbc
01706d6c-6aad-c795-370c-98d0be881bbd
01706d6c-6aad-c795-370c-98d0be881bbe
01706d6c-6aad-c795-370c-98d0be881bbf
            ^ look                 ^ look
                                   
|------------|---------------------|
  millisecs        randomness

ULID string

The ULID string is a sequence of 26 chars. See the ULID specification for more information.

See the section on GUIDs to know how the 128 bits are generated in this library.

// String based on ULID spec
String ulid = UlidCreator.getUlidString();
// String based on ULID spec
// Compatible with RFC-4122 UUID v4
String ulid = UlidCreator.getUlidString4();

Sequence of Strings based on ULID spec:

01E1PPRTMSQ34W7JR5YSND6B8T
01E1PPRTMSQ34W7JR5YSND6B8V
01E1PPRTMSQ34W7JR5YSND6B8W
01E1PPRTMSQ34W7JR5YSND6B8X
01E1PPRTMSQ34W7JR5YSND6B8Y
01E1PPRTMSQ34W7JR5YSND6B8Z
01E1PPRTMSQ34W7JR5YSND6B90
01E1PPRTMSQ34W7JR5YSND6B91
01E1PPRTMTYMX8G17TWSJJZMEE < millisecond changed
01E1PPRTMTYMX8G17TWSJJZMEF
01E1PPRTMTYMX8G17TWSJJZMEG
01E1PPRTMTYMX8G17TWSJJZMEH
01E1PPRTMTYMX8G17TWSJJZMEJ
01E1PPRTMTYMX8G17TWSJJZMEK
01E1PPRTMTYMX8G17TWSJJZMEM
01E1PPRTMTYMX8G17TWSJJZMEN
         ^ look          ^ look
                                   
|---------|--------------|
 millisecs   randomness

How use the UlidSpecCreator directly

These are some examples of using the UlidSpecCreator to create ULID strings:

// with your custom timestamp strategy
TimestampStrategy customStrategy = new CustomTimestampStrategy();
UlidSpecCreator creator = UlidCreator.getUlidSpecCreator()
	.withTimestampStrategy(customStrategy);
String ulid = creator.createString();
// with your custom random strategy that wraps any random generator
RandomStrategy customStrategy = new CustomRandomStrategy();
UlidSpecCreator creator = UlidCreator.getUlidSpecCreator()
	.withRandomStrategy(customStrategy);
String ulid = creator.createString();
// with `java.util.Random` number generator
Random random = new Random();
UlidSpecCreator creator = UlidCreator.getUlidSpecCreator()
    .withRandomGenerator(random);
String ulid = creator.createString();

Benchmark

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

  • ulid-creator v2.1.0:
---------------------------------------------------------------------------
THROUGHPUT                         Mode  Cnt      Score     Error   Units
---------------------------------------------------------------------------
Throughput.JDK_RandomBased         thrpt    5   2196,215 ±  13,668  ops/ms
Throughput.UlidCreator_Ulid        thrpt    5  19224,340 ± 106,231  ops/ms
Throughput.UlidCreator_UlidString  thrpt    5   5006,424 ±  26,946  ops/ms
---------------------------------------------------------------------------
Total time: 00:04:01
---------------------------------------------------------------------------
  • ulid-creator v2.2.0:
---------------------------------------------------------------------------
THROUGHPUT                         Mode  Cnt      Score     Error   Units
---------------------------------------------------------------------------
Throughput.JDK_RandomBased         thrpt    5   2191,690 ±   8,947  ops/ms
Throughput.UlidCreator_Ulid        thrpt    5  19236,123 ± 156,123  ops/ms
Throughput.UlidCreator_UlidString  thrpt    5  12893,016 ± 179,618  ops/ms <- 2.5x faster
---------------------------------------------------------------------------
Total time: 00:04:01
---------------------------------------------------------------------------

The ULID string generation is 2.5x faster in version 2.2.0 than before.

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

See: uuid-creator-benchmark