Skip to content

f4b6a3/ulid-creator

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 

ULID Creator

This is a Java implementation of Universally Unique Lexicographically Sortable Identifier.

In summary:

  • Sorted by generation time;
  • 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, is case insensitive, and has no hyphens.

This project contains a micro benchmark and a good amount of unit tests.

The jar file can be downloaded directly from maven.org.

Read the Javadocs.

Usage

Create a ULID:

Ulid ulid = UlidCreator.getUlid();

Create a Monotonic ULID:

Ulid ulid = UlidCreator.getMonotonicUlid();

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

See more options in maven.org.

Modularity

Module and bundle names are the same as the root package name.

  • JPMS module name: com.github.f4b6a3.ulid
  • OSGi symbolic name: com.github.f4b6a3.ulid

ULID

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

// Generate a ULID
Ulid ulid = UlidCreator.getUlid();

Structure of a series 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

Monotonic ULID is a variant of ULID. The random component is incremented by 1 whenever the current millisecond equals the previous millisecond. Its main advantage is speed.

// Generate a Monotonic ULID
Ulid ulid = UlidCreator.getMonotonicUlid();

Structure of a series 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

Hash ULID

Hash ULID is a "non-standard" variant of ULID. It always returns the same ULID for a specific pair of arguments. It has the same basic structure as a ULID, except that the random component is replaced with the first 10 bytes of an SHA-256 hash.

// Generate a Hash ULID of a string
long time = file.getCreatedAt();
String name = file.getFileName();
Ulid ulid = UlidCreator.getHashUlid(time, name);
// Generate a Hash ULID of a byte array
long time = file.getCreatedAt();
byte[] bytes = file.getFileBinary();
Ulid ulid = UlidCreator.getHashUlid(time, bytes);

Structure of Hash ULIDs:

01GZ8AR53SE5XCA1MN1PGCSDJ0

|---------|--------------|

    time        hash

More Examples

Create a quick ULID:

Ulid ulid = Ulid.fast();

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

Ulid ulid = Ulid.from("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

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 only the time component substring:

String ulidTimePart = ulid.toString()
                          .substring(0, Ulid.TIME_CHARS); // 0123456789

Get only the random component substring:

String ulidRandPart = ulid.toString()
                          .substring(Ulid.TIME_CHARS, Ulid.RANDOM_CHARS); // ABCDEFGHJKMNPQRS

Insert a string between the time and random components efficiently (avoiding concatenation) (#29):

String ulidExpanded = new StringBuilder(ulid.toString())
                          .insert(Ulid.TIME_CHARS, "-INSERTED-")
                          .toString(); // 0123456789-INSERTED-ABCDEFGHJKMNPQRS

A key generator that makes substitution easy if necessary:

package com.example;

import com.github.f4b6a3.ulid.UlidCreator;

public class KeyGenerator {
    public static String next() {
        return UlidCreator.getUlid().toString();
    }
}
// use the generator
String key = KeyGenerator.next();

A UlidFactory with java.util.Random:

// use a `java.util.Random` instance for fast generation
UlidFactory factory = UlidFactory.newInstance(new Random());
// use the factory
Ulid ulid = factory.create();

A UlidFactory with RandomGenerator (JDK 17+):

// use a random function that returns a long value
RandomGenerator random = RandomGenerator.getDefault();
UlidFactory factory = UlidFactory.newInstance(() -> random.nextLong());
// use the factory
Ulid ulid = factory.create();

Benchmark

This section shows benchmarks comparing UlidCreator to UUID.randomUUID().

--------------------------------------------------------------------------------
THROUGHPUT (operations/msec)            Mode  Cnt      Score      Error   Units
--------------------------------------------------------------------------------
UUID_randomUUID                        thrpt    5   1787,601 ±  489,482  ops/ms ( 1.0)
UUID_randomUUID_toString               thrpt    5   1598,467 ±   93,067  ops/ms
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
Ulid_fast                              thrpt    5 100521,737 ±27132,748  ops/ms (56.2)
Ulid_fast_toString                     thrpt    5  50529,743 ± 8970,574  ops/ms
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
UlidCreator_getUlid                    thrpt    5   2443,810 ±  379,149  ops/ms ( 1.3)
UlidCreator_getUlid_toString           thrpt    5   2200,047 ±  539,767  ops/ms
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
UlidCreator_getMonotonicUlid           thrpt    5   9845,810 ± 1239,148  ops/ms ( 5.5)
UlidCreator_getMonotonicUlid_toString  thrpt    5   5748,568 ±  549,121  ops/ms
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
UlidCreator_getHashUlid                thrpt    5   6651,239 ± 2541,774  ops/ms
UlidCreator_getHashUlidString          thrpt    5   6043,582 ± 1879,042  ops/ms
--------------------------------------------------------------------------------
Total time: 00:03:22
--------------------------------------------------------------------------------

System: CPU i7-8565U, 16G RAM, Ubuntu 22.04, JVM 11, rng-tools installed.

To execute the benchmark, run ./benchmark/run.sh.

Other identifier generators

Check out the other ID generators from the same family:

License

This library is Open Source software released under the MIT license.

About

A Java library for generating Universally Unique Lexicographically Sortable Identifiers (ULID)

Topics

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •  

Languages