Skip to content

Commit

Permalink
Merge pull request #12 from azam/develop
Browse files Browse the repository at this point in the history
Release 1.0.4
  • Loading branch information
azam authored Apr 14, 2023
2 parents e93d1e0 + 8545aff commit 1490a73
Show file tree
Hide file tree
Showing 9 changed files with 642 additions and 241 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ jobs:
uses: softprops/action-gh-release@v1
with:
files: |
ulidj-*.pom
ulidj-*.jar
ulidj-*.asc
target/ulidj-*.pom
target/ulidj-*.jar
target/ulidj-*.asc
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.azam.ulidj</groupId>
<artifactId>ulidj</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
<name>ulidj</name>
<description>ULID (Universally Unique Lexicographically Sortable Identifier) generator and parser for Java.</description>
<url>https://github.com/azam/ulidj</url>
Expand Down
33 changes: 26 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
[![Maven Central](https://img.shields.io/maven-central/v/io.azam.ulidj/ulidj)](https://central.sonatype.com/artifact/io.azam.ulidj/ulidj)
[![Build Status](https://github.com/azam/ulidj/actions/workflows/build.yml/badge.svg)](https://github.com/azam/ulidj/actions/workflows/build.yml)

ULID (Universally Unique Lexicographically Sortable Identifier) generator and parser for Java.
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.

Refer [ulid/spec](https://github.com/ulid/spec) for a more detailed ULID specification.
## Features

* Generates ULID to `String` (Crockford's base32) or `byte[]` (128-bit UUID compatible) objects
* Parses ULID from `String` (Crockford's base32) or `byte[]` (128-bit UUID compatible) objects
* Fast and simple static methods
* Includes ULID monotonic generator
* Zero runtime dependencies

## License

Expand Down Expand Up @@ -42,7 +48,7 @@ Add the following tag to `dependencies` tag in your `pom.xml` file. Change the v
<dependency>
<groupId>io.azam.ulidj</groupId>
<artifactId>ulidj</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
</dependency>
```

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

ULID parsing examples:

```java
// ULID string parsing
String ulid = "003JZ9J6G80123456789abcdef";
assert ULID.isValid(ulid);
long ts = ULID.getTimestamp(ulid);
assert ts == 123456789000L;
byte[] entropy = ULID.getEntropy(ulid);

// ULID binary parsing
byte[] ulidBinary = new byte[] { //
// Timestamp part
(byte) 0x01, (byte) 0x33, (byte) 0x7C, (byte) 0x0D, (byte) 0xEF, (byte) 0x00, //
// Entropy part
(byte) 0x10, (byte) 0x20, (byte) 0x30, (byte) 0x40, (byte) 0x50, (byte) 0x60, (byte) 0x70, (byte) 0x80, (byte) 0x90, (byte) 0x10 //
};
assert ULID.isValidBinary(ulidBinary);
long ts = ULID.getTimestampBinary(ulidBinary);
assert ts == 1320636247808L;
byte[] entropy = ULID.getEntropyBinary(ulidBinary);
```

Monotonic ULID generation example:

```java
MonotonicULID ulid = new MonotonicULID();
String ulid1 = ulid.next();
String ulid2 = ulid.next();
String ulid3 = ulid.next();
String ulidString = ulid.generate(); // Generate ULID in string representation
byte[] ulidBinary = ulid.generateBinary(); // Generate ULID in binary representation
```

## Develop
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/io/azam/ulidj/MonotonicULID.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,40 @@ public synchronized String generate() {
}
return ULID.generate(this.lastTimestamp, this.lastEntropy);
}

/**
* Generate ULID binary monotonicly. If this method is called within the same millisecond, last
* entropy will be incremented by 1 and the ULID string of incremented value is returned.<br>
* <br>
* This method will throw a {@link java.lang.IllegalStateException} exception if incremented value
* overflows entropy length (80b-its/10-bytes)
*
* @return ULID binary
*/
public synchronized byte[] generateBinary() {
long now = System.currentTimeMillis();
if (now == this.lastTimestamp) {
// Entropy is big-endian (network byte order) per ULID spec
// Increment last entropy by 1
boolean carry = true;
for (int i = ULID.ENTROPY_LENGTH - 1; i >= 0; i--) {
if (carry) {
byte work = this.lastEntropy[i];
work = (byte) (work + 0x01);
carry = this.lastEntropy[i] == (byte) 0xff && carry;
this.lastEntropy[i] = work;
}
}
// Last byte has carry over
if (carry) {
// Throw error if entropy overflows in same millisecond per ULID spec
throw new IllegalStateException("ULID entropy overflowed for same millisecond");
}
} else {
// Generate new entropy
this.lastTimestamp = now;
this.random.nextBytes(this.lastEntropy);
}
return ULID.generateBinary(this.lastTimestamp, this.lastEntropy);
}
}
Loading

0 comments on commit 1490a73

Please sign in to comment.