2020-02-22 16:07:16 +00:00
2022-03-01 14:16:09 +00:00
ULID Creator
======================================================
2021-01-30 09:51:27 +00:00
2022-03-01 14:16:09 +00:00
This is a Java implementation of [Universally Unique Lexicographically Sortable Identifier ](https://github.com/ulid/spec ).
2020-02-22 16:07:16 +00:00
2022-03-01 14:16:09 +00:00
In summary:
2020-02-22 16:07:16 +00:00
2022-03-01 14:16:09 +00:00
* Sorted by generation time;
2020-10-18 00:50:37 +00:00
* Can be stored as a UUID/GUID;
* Can be stored as a string of 26 chars;
2021-01-30 09:51:27 +00:00
* Can be stored as an array of 16 bytes;
2020-10-18 00:50:37 +00:00
* String format is encoded to [Crockford's base32 ](https://www.crockford.com/base32.html );
2022-03-01 14:16:09 +00:00
* String format is URL safe, is case insensitive, and has no hyphens.
2022-09-17 12:45:57 +00:00
This project contains a [micro benchmark ](https://github.com/f4b6a3/ulid-creator/tree/master/benchmark ) and a good amount of [unit tests ](https://github.com/f4b6a3/ulid-creator/tree/master/src/test/java/com/github/f4b6a3/ulid ).
The jar file can be downloaded directly from [maven.org ](https://repo1.maven.org/maven2/com/github/f4b6a3/ulid-creator/ ).
Read the [Javadocs ](https://javadoc.io/doc/com.github.f4b6a3/ulid-creator ).
2020-10-18 00:50:37 +00:00
2023-04-30 06:39:38 +00:00
Usage
2020-02-22 16:07:16 +00:00
------------------------------------------------------
2020-10-18 00:50:37 +00:00
Create a ULID:
2020-02-22 16:07:16 +00:00
```java
2021-01-30 09:51:27 +00:00
Ulid ulid = UlidCreator.getUlid();
2020-02-22 16:07:16 +00:00
```
2021-01-30 09:51:27 +00:00
Create a Monotonic ULID:
2020-02-22 16:07:16 +00:00
```java
2021-01-30 09:51:27 +00:00
Ulid ulid = UlidCreator.getMonotonicUlid();
2020-02-22 16:07:16 +00:00
```
2023-04-30 06:39:38 +00:00
### Dependency
2020-02-22 16:07:16 +00:00
2020-02-23 17:08:30 +00:00
Add these lines to your `pom.xml` .
```xml
<!-- https://search.maven.org/artifact/com.github.f4b6a3/ulid - creator -->
< dependency >
< groupId > com.github.f4b6a3< / groupId >
< artifactId > ulid-creator< / artifactId >
2023-12-17 19:33:41 +00:00
< version > 5.2.3< / version >
2020-02-23 17:08:30 +00:00
< / dependency >
```
2020-04-19 23:18:24 +00:00
See more options in [maven.org ](https://search.maven.org/artifact/com.github.f4b6a3/ulid-creator ).
2020-02-22 16:07:16 +00:00
2021-09-04 04:49:53 +00:00
### 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`
2021-07-17 17:02:34 +00:00
2020-10-18 00:50:37 +00:00
### ULID
2020-02-22 16:07:16 +00:00
2023-04-30 06:33:23 +00:00
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.
2020-02-22 16:07:16 +00:00
```java
2021-01-30 09:51:27 +00:00
// Generate a ULID
Ulid ulid = UlidCreator.getUlid();
2020-02-22 16:07:16 +00:00
```
2023-04-30 06:33:23 +00:00
Structure of a series of ULIDs:
2020-02-22 16:07:16 +00:00
```text
2021-01-30 09:51:27 +00:00
01EX8Y21KBH49ZZCA7KSKH6X1C
01EX8Y21KBJTFK0JV5J20QPQNR
01EX8Y21KBG2CS1V6WQCTVM7K6
01EX8Y21KB8HPZNBP3PTW7HVEY
01EX8Y21KB3HZV38VAPTPAG1TY
01EX8Y21KB9FTEJHPAGAKYG9Z8
01EX8Y21KBQGKGH2SVPQAYEFFC
01EX8Y21KBY17J9WR9KQR8SE7H
01EX8Y21KCVHYSJGVK4HBXDMR9 < millisecond changed
01EX8Y21KC668W3PEDEAGDHMVG
01EX8Y21KC53D2S5ADQ2EST327
01EX8Y21KCPQ3TENMTY1S7HV56
01EX8Y21KC3755QF9STQEV05EB
01EX8Y21KC5ZSHK908GMDK69WE
01EX8Y21KCSGJS8S1FVS06B3SX
01EX8Y21KC6ZBWQ0JBV337R1CN
^ look
|---------|--------------|
time random
2020-02-22 16:07:16 +00:00
```
2021-01-30 09:51:27 +00:00
### Monotonic ULID
2020-02-22 16:07:16 +00:00
2023-04-30 06:33:23 +00:00
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* .
2020-07-04 15:25:37 +00:00
```java
2021-01-30 09:51:27 +00:00
// Generate a Monotonic ULID
Ulid ulid = UlidCreator.getMonotonicUlid();
2020-07-04 15:25:37 +00:00
```
2023-04-30 06:33:23 +00:00
Structure of a series of Monotonic ULIDs:
2020-07-04 15:25:37 +00:00
```text
2021-01-30 09:51:27 +00:00
01EX8Y7M8MDVX3M3EQG69EEMJW
01EX8Y7M8MDVX3M3EQG69EEMJX
01EX8Y7M8MDVX3M3EQG69EEMJY
01EX8Y7M8MDVX3M3EQG69EEMJZ
01EX8Y7M8MDVX3M3EQG69EEMK0
01EX8Y7M8MDVX3M3EQG69EEMK1
01EX8Y7M8MDVX3M3EQG69EEMK2
01EX8Y7M8MDVX3M3EQG69EEMK3
01EX8Y7M8N1G30CYF2PJR23J2J < millisecond changed
01EX8Y7M8N1G30CYF2PJR23J2K
01EX8Y7M8N1G30CYF2PJR23J2M
01EX8Y7M8N1G30CYF2PJR23J2N
01EX8Y7M8N1G30CYF2PJR23J2P
01EX8Y7M8N1G30CYF2PJR23J2Q
01EX8Y7M8N1G30CYF2PJR23J2R
01EX8Y7M8N1G30CYF2PJR23J2S
2020-07-04 15:25:37 +00:00
^ look ^ look
2021-01-30 09:51:27 +00:00
2020-07-04 15:25:37 +00:00
|---------|--------------|
2021-01-30 09:51:27 +00:00
time random
```
2023-04-30 06:33:23 +00:00
### 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.
```java
// Generate a Hash ULID of a string
long time = file.getCreatedAt();
String name = file.getFileName();
Ulid ulid = UlidCreator.getHashUlid(time, name);
```
```java
// 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:
```text
01GZ8AR53SE5XCA1MN1PGCSDJ0
|---------|--------------|
time hash
```
2021-11-29 02:09:48 +00:00
### More Examples
2021-01-30 09:51:27 +00:00
2022-10-22 18:01:18 +00:00
Create a quick ULID:
```java
Ulid ulid = Ulid.fast();
```
---
2021-01-30 09:51:27 +00:00
Create a ULID from a canonical string (26 chars):
```java
Ulid ulid = Ulid.from("0123456789ABCDEFGHJKMNPQRS");
```
2021-11-29 02:09:48 +00:00
---
2021-01-30 09:51:27 +00:00
Convert a ULID into a canonical string in lower case:
```java
String string = ulid.toLowerCase(); // 0123456789abcdefghjkmnpqrs
```
2021-11-29 02:09:48 +00:00
---
2021-01-30 09:51:27 +00:00
Convert a ULID into a UUID:
```java
UUID uuid = ulid.toUuid(); // 0110c853-1d09-52d8-d73e-1194e95b5f19
2020-07-04 15:25:37 +00:00
```
2021-11-29 02:09:48 +00:00
---
2021-01-30 09:51:27 +00:00
Convert a ULID into a [RFC-4122 ](https://tools.ietf.org/html/rfc4122 ) UUID v4:
2020-07-04 15:25:37 +00:00
2021-01-30 09:51:27 +00:00
```java
UUID uuid = ulid.toRfc4122().toUuid(); // 0110c853-1d09-42d8-973e-1194e95b5f19
// ^ UUID v4
```
2021-11-29 02:09:48 +00:00
---
2021-01-30 09:51:27 +00:00
Get the creation instant of a ULID:
2020-02-22 16:07:16 +00:00
```java
2021-01-30 09:51:27 +00:00
Instant instant = ulid.getInstant(); // 2007-02-16T02:13:14.633Z
2020-07-05 03:49:48 +00:00
```
2021-01-30 09:51:27 +00:00
2023-08-30 06:37:05 +00:00
---
2021-02-13 23:14:31 +00:00
```java
// static method
Instant instant = Ulid.getInstant("0123456789ABCDEFGHJKMNPQRS"); // 2007-02-16T02:13:14.633Z
```
2023-08-30 06:37:05 +00:00
---
2023-08-30 06:34:08 +00:00
Get only the time component substring:
```java
String ulidTimePart = ulid.toString()
.substring(0, Ulid.TIME_CHARS); // 0123456789
```
2023-08-30 06:37:05 +00:00
---
2023-08-30 06:34:08 +00:00
Get only the random component substring:
```java
String ulidRandPart = ulid.toString()
.substring(Ulid.TIME_CHARS, Ulid.RANDOM_CHARS); // ABCDEFGHJKMNPQRS
```
2023-08-30 06:37:05 +00:00
---
2023-08-30 06:34:08 +00:00
Insert a string between the time and random components efficiently (avoiding concatenation) ([#29](https://github.com/f4b6a3/ulid-creator/pull/29)):
```java
String ulidExpanded = new StringBuilder(ulid.toString())
.insert(Ulid.TIME_CHARS, "-INSERTED-")
.toString(); // 0123456789-INSERTED-ABCDEFGHJKMNPQRS
```
2021-11-29 02:09:48 +00:00
---
2021-02-13 23:14:31 +00:00
2021-11-29 02:28:06 +00:00
A key generator that makes substitution easy if necessary:
2021-11-27 05:45:30 +00:00
```java
package com.example;
import com.github.f4b6a3.ulid.UlidCreator;
public class KeyGenerator {
public static String next() {
return UlidCreator.getUlid().toString();
}
}
```
```java
2023-04-30 06:33:23 +00:00
// use the generator
2021-11-27 05:48:08 +00:00
String key = KeyGenerator.next();
2021-11-27 05:45:30 +00:00
```
2021-11-29 02:09:48 +00:00
---
2021-11-29 02:28:06 +00:00
A `UlidFactory` with `java.util.Random` :
2021-01-30 09:51:27 +00:00
2020-07-05 03:50:30 +00:00
```java
2021-08-08 04:26:04 +00:00
// use a `java.util.Random` instance for fast generation
UlidFactory factory = UlidFactory.newInstance(new Random());
2020-02-22 16:07:16 +00:00
```
2022-07-09 17:43:36 +00:00
```java
// use the factory
Ulid ulid = factory.create();
```
---
A `UlidFactory` with `RandomGenerator` (JDK 17+):
```java
// use a random function that returns a long value
RandomGenerator random = RandomGenerator.getDefault();
UlidFactory factory = UlidFactory.newInstance(() -> random.nextLong());
```
2021-11-15 10:56:11 +00:00
```java
// use the factory
2021-02-13 23:14:31 +00:00
Ulid ulid = factory.create();
2021-01-30 09:51:27 +00:00
```
2021-11-29 02:09:48 +00:00
---
2020-07-04 15:25:37 +00:00
Benchmark
------------------------------------------------------
2022-09-17 12:45:57 +00:00
This section shows benchmarks comparing `UlidCreator` to `UUID.randomUUID()` .
2020-07-04 15:25:37 +00:00
```
2020-11-16 04:39:52 +00:00
--------------------------------------------------------------------------------
2022-09-17 12:45:57 +00:00
THROUGHPUT (operations/msec) Mode Cnt Score Error Units
2021-07-25 20:55:29 +00:00
--------------------------------------------------------------------------------
2023-04-30 06:33:23 +00:00
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
2022-03-01 14:16:09 +00:00
- - - - - - - - - - - - - - - - - - - - - - - - - - -
2023-04-30 06:33:23 +00:00
UlidCreator_getUlid thrpt 5 2443,810 ± 379,149 ops/ms ( 1.3)
UlidCreator_getUlid_toString thrpt 5 2200,047 ± 539,767 ops/ms
2022-10-22 18:01:18 +00:00
- - - - - - - - - - - - - - - - - - - - - - - - - - -
2023-04-30 06:33:23 +00:00
UlidCreator_getMonotonicUlid thrpt 5 9845,810 ± 1239,148 ops/ms ( 5.5)
UlidCreator_getMonotonicUlid_toString thrpt 5 5748,568 ± 549,121 ops/ms
2022-03-01 14:16:09 +00:00
- - - - - - - - - - - - - - - - - - - - - - - - - - -
2023-04-30 06:33:23 +00:00
UlidCreator_getHashUlid thrpt 5 6651,239 ± 2541,774 ops/ms
UlidCreator_getHashUlidString thrpt 5 6043,582 ± 1879,042 ops/ms
2021-07-25 20:55:29 +00:00
--------------------------------------------------------------------------------
2023-04-30 06:33:23 +00:00
Total time: 00:03:22
2021-07-25 20:55:29 +00:00
--------------------------------------------------------------------------------
2020-07-04 15:25:37 +00:00
```
2022-09-17 12:45:57 +00:00
System: CPU i7-8565U, 16G RAM, Ubuntu 22.04, JVM 11, rng-tools installed.
2020-07-04 15:25:37 +00:00
2021-07-25 20:55:29 +00:00
To execute the benchmark, run `./benchmark/run.sh` .
2020-07-04 15:25:37 +00:00
2021-07-25 20:55:29 +00:00
Other identifier generators
2020-07-04 15:25:37 +00:00
-------------------------------------------
2021-11-29 02:09:48 +00:00
2022-03-01 14:16:09 +00:00
Check out the other ID generators from the same family:
2021-11-29 02:09:48 +00:00
2022-03-01 14:16:09 +00:00
* [UUID Creator ](https://github.com/f4b6a3/uuid-creator ): Universally Unique Identifiers
* [TSID Creator ](https://github.com/f4b6a3/tsid-creator ): Time Sortable Identifiers
* [KSUID Creator ](https://github.com/f4b6a3/ksuid-creator ): K-Sortable Globally Unique Identifiers
License
------------------------------------------------------
2021-01-30 09:51:27 +00:00
2022-03-01 14:16:09 +00:00
This library is Open Source software released under the [MIT license ](https://opensource.org/licenses/MIT ).
2022-09-17 12:45:57 +00:00