2020-02-22 16:07:16 +00:00
2021-01-30 09:51:27 +00:00
2020-02-24 07:53:01 +00:00
# ULID Creator
2020-02-22 16:07:16 +00:00
2021-07-17 17:02:34 +00:00
A Java library for generating [ULIDs ](https://github.com/ulid/spec ) (Universally Unique Lexicographically Sortable Identifier).
2020-02-22 16:07:16 +00:00
2020-10-18 00:50:37 +00:00
* Generated in lexicographical order;
* 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 );
2021-01-30 09:51:27 +00:00
* String format is URL safe and case insensitive.
2020-10-18 00:50:37 +00:00
2020-02-22 16:07:16 +00:00
How to Use
------------------------------------------------------
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
```
### Maven dependency
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 >
2021-07-18 04:21:41 +00:00
< version > 3.2.0< / 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-07-17 17:02:34 +00:00
Module name: `com.github.f4b6a3.ulid` .
2020-10-18 00:50:37 +00:00
### ULID
2020-02-22 16:07:16 +00:00
2021-01-30 12:29:46 +00:00
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.
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
```
2020-11-08 14:15:22 +00:00
```java
2021-01-30 09:51:27 +00:00
// Generate a ULID with a specific time
Ulid ulid = UlidCreator.getUlid(1234567890);
2020-11-08 14:15:22 +00:00
```
2021-01-30 09:51:27 +00:00
Sequence 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
2021-01-30 12:29:46 +00:00
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.
2020-07-04 15:25:37 +00:00
2021-01-30 09:51:27 +00:00
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.
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
```
2020-11-08 14:15:22 +00:00
```java
2021-01-30 09:51:27 +00:00
// Generate a Monotonic ULID with a specific time
Ulid ulid = UlidCreator.getMonotonicUlid(1234567890);
2020-11-08 14:15:22 +00:00
```
2021-01-30 09:51:27 +00:00
Sequence 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
```
### Other usage examples
Create a ULID from a canonical string (26 chars):
```java
Ulid ulid = Ulid.from("0123456789ABCDEFGHJKMNPQRS");
```
Convert a ULID into a canonical string in upper case:
```java
String string = ulid.toUpperCase(); // 0123456789ABCDEFGHJKMNPQRS
```
Convert a ULID into a canonical string in lower case:
```java
String string = ulid.toLowerCase(); // 0123456789abcdefghjkmnpqrs
```
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-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
```
Convert a ULID into a byte array:
```java
byte[] bytes = ulid.toBytes(); // 16 bytes (128 bits)
```
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
2021-02-13 23:14:31 +00:00
```java
// static method
Instant instant = Ulid.getInstant("0123456789ABCDEFGHJKMNPQRS"); // 2007-02-16T02:13:14.633Z
```
2021-01-30 09:51:27 +00:00
Get the time component of a ULID:
2020-07-05 03:50:30 +00:00
```java
2021-01-30 09:51:27 +00:00
long time = ulid.getTime(); // 1171591994633
2020-07-05 03:49:48 +00:00
```
2021-01-30 09:51:27 +00:00
2021-02-13 23:14:31 +00:00
```java
// static method
long time = Ulid.getTime("0123456789ABCDEFGHJKMNPQRS"); // 1171591994633
```
2021-01-30 09:51:27 +00:00
Get the random component of a ULID:
```java
byte[] random = ulid.getRandom(); // 10 bytes (80 bits)
```
2021-02-13 23:14:31 +00:00
```java
// static method
byte[] random = Ulid.getRandom("0123456789ABCDEFGHJKMNPQRS"); // 10 bytes (80 bits)
```
2021-07-18 04:21:41 +00:00
Use a `UlidFactory` with `java.util.Random` :
2021-01-30 09:51:27 +00:00
2020-07-05 03:50:30 +00:00
```java
2021-07-18 04:21:41 +00:00
// use a `Random` instance
UlidFactory factory = new DefaultFactory(new Random());
2021-02-13 23:14:31 +00:00
Ulid ulid = factory.create();
2020-02-22 16:07:16 +00:00
```
2021-07-18 04:21:41 +00:00
Use a `UlidFactory` with a random generator of your choice:
2021-01-30 09:51:27 +00:00
```java
2021-07-18 04:21:41 +00:00
// use a method of any RNG with this signature: `void nextBytes(byte[])`
2021-01-30 09:51:27 +00:00
import com.github.niceguy.random.AwesomeRandom; // a hypothetical RNG
2021-07-18 04:21:41 +00:00
UlidFactory factory = new DefaultFactory(new AwesomeRandom()::nextBytes);
2021-02-13 23:14:31 +00:00
Ulid ulid = factory.create();
2021-01-30 09:51:27 +00:00
```
2021-07-17 17:02:34 +00:00
(*) as long as it provides a void method like `nextBytes(byte[])` .
2021-01-30 09:51:27 +00:00
2020-07-04 15:25:37 +00:00
Benchmark
------------------------------------------------------
This section shows benchmarks comparing `UlidCreator` to `java.util.UUID` .
```
2020-11-16 04:39:52 +00:00
================================================================================
2021-01-30 09:51:27 +00:00
THROUGHPUT (operations/msec) Mode Cnt Score Error Units
2020-11-16 04:39:52 +00:00
================================================================================
2021-01-30 09:51:27 +00:00
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
2020-11-16 04:39:52 +00:00
--------------------------------------------------------------------------------
2021-01-30 09:51:27 +00:00
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
2020-11-16 04:39:52 +00:00
================================================================================
2021-01-30 09:51:27 +00:00
Total time: 00:09:22
2020-11-16 04:39:52 +00:00
================================================================================
2020-07-04 15:25:37 +00:00
```
2020-11-16 04:39:52 +00:00
System: JVM 8, Ubuntu 20.04, CPU i5-3330, 8G RAM.
2020-07-04 15:25:37 +00:00
See: [uuid-creator-benchmark ](https://github.com/fabiolimace/uuid-creator-benchmark )
2021-01-30 09:51:27 +00:00
Other generators
2020-07-04 15:25:37 +00:00
-------------------------------------------
2021-01-30 09:51:27 +00:00
* [UUID Creator ](https://github.com/f4b6a3/uuid-creator ): for generating UUIDs
2021-07-18 04:21:41 +00:00
* [TSID Creator ](https://github.com/f4b6a3/tsid-creator ): for generating TSIDs
* [KSUID Creator ](https://github.com/f4b6a3/ksuid-creator ): for generating KSUIDs
2021-01-30 09:51:27 +00:00