Skip to content

Commit 1490a73

Browse files
authored
Merge pull request #12 from azam/develop
Release 1.0.4
2 parents e93d1e0 + 8545aff commit 1490a73

File tree

9 files changed

+642
-241
lines changed

9 files changed

+642
-241
lines changed

.github/workflows/publish.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ jobs:
3838
uses: softprops/action-gh-release@v1
3939
with:
4040
files: |
41-
ulidj-*.pom
42-
ulidj-*.jar
43-
ulidj-*.asc
41+
target/ulidj-*.pom
42+
target/ulidj-*.jar
43+
target/ulidj-*.asc

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>io.azam.ulidj</groupId>
55
<artifactId>ulidj</artifactId>
6-
<version>1.0.3</version>
6+
<version>1.0.4</version>
77
<name>ulidj</name>
88
<description>ULID (Universally Unique Lexicographically Sortable Identifier) generator and parser for Java.</description>
99
<url>https://github.com/azam/ulidj</url>

readme.md

+26-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44
[![Maven Central](https://img.shields.io/maven-central/v/io.azam.ulidj/ulidj)](https://central.sonatype.com/artifact/io.azam.ulidj/ulidj)
55
[![Build Status](https://github.com/azam/ulidj/actions/workflows/build.yml/badge.svg)](https://github.com/azam/ulidj/actions/workflows/build.yml)
66

7-
ULID (Universally Unique Lexicographically Sortable Identifier) generator and parser for Java.
7+
ULID (Universally Unique Lexicographically Sortable Identifier) generator and parser for Java. Refer [ulid/spec](https://github.com/ulid/spec) for a more detailed ULID specification.
88

9-
Refer [ulid/spec](https://github.com/ulid/spec) for a more detailed ULID specification.
9+
## Features
10+
11+
* Generates ULID to `String` (Crockford's base32) or `byte[]` (128-bit UUID compatible) objects
12+
* Parses ULID from `String` (Crockford's base32) or `byte[]` (128-bit UUID compatible) objects
13+
* Fast and simple static methods
14+
* Includes ULID monotonic generator
15+
* Zero runtime dependencies
1016

1117
## License
1218

@@ -42,7 +48,7 @@ Add the following tag to `dependencies` tag in your `pom.xml` file. Change the v
4248
<dependency>
4349
<groupId>io.azam.ulidj</groupId>
4450
<artifactId>ulidj</artifactId>
45-
<version>1.0.3</version>
51+
<version>1.0.4</version>
4652
</dependency>
4753
```
4854

@@ -55,26 +61,39 @@ String ulid1 = ULID.random();
5561
String ulid2 = ULID.random(ThreadLocalRandom.current());
5662
String ulid3 = ULID.random(SecureRandom.newInstance("SHA1PRNG"));
5763
byte[] entropy = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 };
58-
String ulid4 = ULID.generate(System.currentTimeMillis(), entropy);
64+
String ulid4 = ULID.generate(System.currentTimeMillis(), entropy); // Generate ULID in string representation
65+
byte[] ulid5 = ULID.generateBinary(System.currentTimeMillis(), entropy); // Generate ULID in binary representation
5966
```
6067

6168
ULID parsing examples:
6269

6370
```java
71+
// ULID string parsing
6472
String ulid = "003JZ9J6G80123456789abcdef";
6573
assert ULID.isValid(ulid);
6674
long ts = ULID.getTimestamp(ulid);
6775
assert ts == 123456789000L;
6876
byte[] entropy = ULID.getEntropy(ulid);
77+
78+
// ULID binary parsing
79+
byte[] ulidBinary = new byte[] { //
80+
// Timestamp part
81+
(byte) 0x01, (byte) 0x33, (byte) 0x7C, (byte) 0x0D, (byte) 0xEF, (byte) 0x00, //
82+
// Entropy part
83+
(byte) 0x10, (byte) 0x20, (byte) 0x30, (byte) 0x40, (byte) 0x50, (byte) 0x60, (byte) 0x70, (byte) 0x80, (byte) 0x90, (byte) 0x10 //
84+
};
85+
assert ULID.isValidBinary(ulidBinary);
86+
long ts = ULID.getTimestampBinary(ulidBinary);
87+
assert ts == 1320636247808L;
88+
byte[] entropy = ULID.getEntropyBinary(ulidBinary);
6989
```
7090

7191
Monotonic ULID generation example:
7292

7393
```java
7494
MonotonicULID ulid = new MonotonicULID();
75-
String ulid1 = ulid.next();
76-
String ulid2 = ulid.next();
77-
String ulid3 = ulid.next();
95+
String ulidString = ulid.generate(); // Generate ULID in string representation
96+
byte[] ulidBinary = ulid.generateBinary(); // Generate ULID in binary representation
7897
```
7998

8099
## Develop

src/main/java/io/azam/ulidj/MonotonicULID.java

+36
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,40 @@ public synchronized String generate() {
108108
}
109109
return ULID.generate(this.lastTimestamp, this.lastEntropy);
110110
}
111+
112+
/**
113+
* Generate ULID binary monotonicly. If this method is called within the same millisecond, last
114+
* entropy will be incremented by 1 and the ULID string of incremented value is returned.<br>
115+
* <br>
116+
* This method will throw a {@link java.lang.IllegalStateException} exception if incremented value
117+
* overflows entropy length (80b-its/10-bytes)
118+
*
119+
* @return ULID binary
120+
*/
121+
public synchronized byte[] generateBinary() {
122+
long now = System.currentTimeMillis();
123+
if (now == this.lastTimestamp) {
124+
// Entropy is big-endian (network byte order) per ULID spec
125+
// Increment last entropy by 1
126+
boolean carry = true;
127+
for (int i = ULID.ENTROPY_LENGTH - 1; i >= 0; i--) {
128+
if (carry) {
129+
byte work = this.lastEntropy[i];
130+
work = (byte) (work + 0x01);
131+
carry = this.lastEntropy[i] == (byte) 0xff && carry;
132+
this.lastEntropy[i] = work;
133+
}
134+
}
135+
// Last byte has carry over
136+
if (carry) {
137+
// Throw error if entropy overflows in same millisecond per ULID spec
138+
throw new IllegalStateException("ULID entropy overflowed for same millisecond");
139+
}
140+
} else {
141+
// Generate new entropy
142+
this.lastTimestamp = now;
143+
this.random.nextBytes(this.lastEntropy);
144+
}
145+
return ULID.generateBinary(this.lastTimestamp, this.lastEntropy);
146+
}
111147
}

0 commit comments

Comments
 (0)