+ * ULID is 128-bit value that has two components: + *
+ * ULID has 128-bit compatibility with {@link UUID}. Like a UUID, a ULID can + * also be stored as a 16-byte array. + *
+ * Instances of this class are immutable.
*
- * The ULID has two components:
- *
- * - Time component: a part of 48 bits that represent the amount of milliseconds
- * since Unix Epoch, 1970-01-01.
- *
- * - Random component: a byte array of 80 bits that has a random value generated
- * a secure random generator.
- *
- * Instances of this class are immutable.
+ * @see ULID Specification
*/
public final class Ulid implements Serializable, Comparable
* Useful to make copies of ULIDs.
*
* @param ulid a ULID
@@ -154,7 +177,10 @@ public final class Ulid implements Serializable, Comparable
+ * If you want to make a copy of a {@link UUID}, use {@link Ulid#from(UUID)}
+ * instead.
*
* @param mostSignificantBits the first 8 bytes as a long value
* @param leastSignificantBits the last 8 bytes as a long value
@@ -165,10 +191,17 @@ public final class Ulid implements Serializable, Comparable
+ * Time parameter is the number of milliseconds since 1970-01-01 (Unix epoch).
+ * It must be a positive number not larger than 2^48-1.
+ *
+ * Random parameter must be an array of 10 bytes.
*
- * @param time the time component in milliseconds since 1970-01-01
- * @param random the random component in byte array
+ * @param time the the number of milliseconds since 1970-01-01
+ * @param random an array of 10 bytes
+ * @throws IllegalArgumentException if time is negative or larger than 2^48-1
+ * @throws IllegalArgumentException if random is null or its length is not 10
*/
public Ulid(long time, byte[] random) {
@@ -177,7 +210,7 @@ public final class Ulid implements Serializable, Comparable
* The input string must be 26 characters long and must contain only characters
* from Crockford's base 32 alphabet.
- *
+ *
* The first character of the input string must be between 0 and 7.
*
* @param string a canonical string
* @return a ULID
+ * @throws IllegalArgumentException if the input string is invalid
+ * @see Crockford's Base 32
*/
public static Ulid from(String string) {
@@ -306,8 +342,10 @@ public final class Ulid implements Serializable, Comparable
+ * A ULID has 128-bit compatibility with a {@link UUID}.
+ *
+ * If you need a RFC-4122 UUIDv4 do this: {@code Ulid.toRfc4122().toUuid()}.
*
* @return a UUID.
*/
@@ -347,16 +385,15 @@ public final class Ulid implements Serializable, Comparable
* The output string is 26 characters long and contains only characters from
- * Crockford's base 32 alphabet.
- *
+ * Crockford's Base 32 alphabet.
+ *
* For lower case string, use the shorthand {@code Ulid#toLowerCase()}, instead
* of {@code Ulid#toString()#toLowerCase()}.
*
- * See: https://www.crockford.com/base32.html
- *
* @return a ULID string
+ * @see Crockford's Base 32
*/
@Override
public String toString() {
@@ -365,47 +402,32 @@ public final class Ulid implements Serializable, Comparable
* The output string is 26 characters long and contains only characters from
- * Crockford's base 32 alphabet.
- *
+ * Crockford's Base 32 alphabet.
+ *
* It is a shorthand at least twice as fast as
* {@code Ulid.toString().toLowerCase()}.
*
- * See: https://www.crockford.com/base32.html
- *
* @return a string
+ * @see Crockford's Base 32
*/
public String toLowerCase() {
return toString(ALPHABET_LOWERCASE);
}
/**
- * Converts the ULID into into another ULID that is compatible with UUID v4.
- *
+ * Converts the ULID into into another ULID that is compatible with UUIDv4.
+ *
* The bytes of the returned ULID are compliant with the RFC-4122 version 4.
- *
- * If you need a RFC-4122 UUID v4 do this: {@code Ulid.toRfc4122().toUuid()}.
- *
- * Read: https://tools.ietf.org/html/rfc4122
- *
- * ### RFC-4122 - 4.4. Algorithms for Creating a UUID from Truly Random or
- * Pseudo-Random Numbers
- *
- * The version 4 UUID is meant for generating UUIDs from truly-random or
- * pseudo-random numbers.
- *
- * The algorithm is as follows:
- *
- * - Set the two most significant bits (bits 6 and 7) of the
- * clock_seq_hi_and_reserved to zero and one, respectively.
- *
- * - Set the four most significant bits (bits 12 through 15) of the
- * time_hi_and_version field to the 4-bit version number from Section 4.1.3.
- *
- * - Set all the other bits to randomly (or pseudo-randomly) chosen values.
+ *
+ * If you need a RFC-4122 UUIDv4 do this: {@code Ulid.toRfc4122().toUuid()}.
+ *
+ * Note: If you use this method, you can not get the original ULID, since
+ * it changes 6 bits of it to generate a UUIDv4.
*
* @return a ULID
+ * @see RFC-4122
*/
public Ulid toRfc4122() {
@@ -419,10 +441,10 @@ public final class Ulid implements Serializable, Comparable
* The instant of creation is extracted from the time component.
*
- * @return {@link Instant}
+ * @return the {@link Instant} of creation
*/
public Instant getInstant() {
return Instant.ofEpochMilli(this.getTime());
@@ -430,11 +452,12 @@ public final class Ulid implements Serializable, Comparable
* The instant of creation is extracted from the time component.
*
* @param string a canonical string
- * @return {@link Instant}
+ * @return the {@link Instant} of creation
+ * @throws IllegalArgumentException if the input string is invalid
*/
public static Instant getInstant(String string) {
return Instant.ofEpochMilli(getTime(string));
@@ -442,11 +465,11 @@ public final class Ulid implements Serializable, Comparable
* The time component is a number between 0 and 2^48-1. It is equivalent to the
* count of milliseconds since 1970-01-01 (Unix epoch).
*
- * @return a number of milliseconds.
+ * @return a number of milliseconds
*/
public long getTime() {
return this.msb >>> 16;
@@ -454,12 +477,13 @@ public final class Ulid implements Serializable, Comparable
* The time component is a number between 0 and 2^48-1. It is equivalent to the
* count of milliseconds since 1970-01-01 (Unix epoch).
*
* @param string a canonical string
- * @return a number of milliseconds.
+ * @return a number of milliseconds
+ * @throws IllegalArgumentException if the input string is invalid
*/
public static long getTime(String string) {
@@ -483,7 +507,7 @@ public final class Ulid implements Serializable, Comparable
* The random component is an array of 10 bytes (80 bits).
*
* @return a byte array
@@ -509,11 +533,12 @@ public final class Ulid implements Serializable, Comparable
* The random component is an array of 10 bytes (80 bits).
*
* @param string a canonical string
* @return a byte array
+ * @throws IllegalArgumentException if the input string is invalid
*/
public static byte[] getRandom(String string) {
@@ -577,19 +602,20 @@ public final class Ulid implements Serializable, Comparable
* Since the random component contains 80 bits:
- *
- * (1) This method can generate up to 1208925819614629174706176 (2^80) ULIDs per
- * millisecond;
- *
- * (2) This method can generate monotonic increasing ULIDs 99.999999999999992%
- * ((2^80 - 10^9) / (2^80)) of the time within a single millisecond interval,
- * considering an unrealistic rate of 1,000,000,000 ULIDs per millisecond.
- *
+ *
* Due to (1) and (2), it does not throw the error message recommended by the
* specification. When an overflow occurs in the random 80 bits, the time
- * component is simply incremented.
+ * component is simply incremented to maintain monotonicity.
*
* @return a ULID
*/
@@ -607,39 +633,56 @@ public final class Ulid implements Serializable, Comparable
* The input string must be 26 characters long and must contain only characters
* from Crockford's base 32 alphabet.
- *
+ *
* The first character of the input string must be between 0 and 7.
*
- * @param string a string
- * @return true if valid
+ * @param string a canonical string
+ * @return true if the input string is valid
+ * @see Crockford's Base 32
*/
public static boolean isValid(String string) {
return string != null && isValidCharArray(string.toCharArray());
}
+ /**
+ * Returns a hash code value for the ULID.
+ */
@Override
public int hashCode() {
final long bits = msb ^ lsb;
return (int) (bits ^ (bits >>> 32));
}
+ /**
+ * Checks if some other ULID is equal to this one.
+ */
@Override
- public boolean equals(Object obj) {
- if (obj == null)
+ public boolean equals(Object other) {
+ if (other == null)
return false;
- if (obj.getClass() != Ulid.class)
+ if (other.getClass() != Ulid.class)
return false;
- Ulid that = (Ulid) obj;
+ Ulid that = (Ulid) other;
if (lsb != that.lsb)
return false;
- if (msb != that.msb)
+ else if (msb != that.msb)
return false;
return true;
}
+ /**
+ * Compares two ULIDs as unsigned 128-bit integers.
+ *
+ * The first of two ULIDs is greater than the second if the most significant
+ * byte in which they differ is greater for the first UUID.
+ *
+ * @param that a ULID to be compared with
+ * @return -1, 0 or 1 as {@code this} is less than, equal to, or greater than
+ * {@code that}
+ */
@Override
public int compareTo(Ulid that) {
@@ -665,7 +708,7 @@ public final class Ulid implements Serializable, Comparable
+ * Both types of ULID can be easily created by this generator, i.e. monotonic
+ * and non-monotonic.
*/
public final class UlidCreator {
@@ -45,8 +38,6 @@ public final class UlidCreator {
/**
* Returns a ULID.
*
- * The random component is always reset to a new random value.
- *
* @return a ULID
*/
public static Ulid getUlid() {
@@ -56,9 +47,7 @@ public final class UlidCreator {
/**
* Returns a ULID with a given time.
*
- * The time must be the number of milliseconds since 1970-01-01 (Unix epoch).
- *
- * @param time a given time
+ * @param time a number of milliseconds since 1970-01-01 (Unix epoch).
* @return a ULID
*/
public static Ulid getUlid(final long time) {
@@ -68,11 +57,6 @@ public final class UlidCreator {
/**
* Returns a Monotonic ULID.
*
- * The random component is reset to a new value whenever the time changes.
- *
- * If more than one ULID is generated within the same time, the random component
- * is incremented by one.
- *
* @return a ULID
*/
public static Ulid getMonotonicUlid() {
@@ -82,14 +66,7 @@ public final class UlidCreator {
/**
* Returns a Monotonic ULID with a given time.
*
- * The time must be the number of milliseconds since 1970-01-01 (Unix epoch).
- *
- * The random component is reset to a new value whenever the time changes.
- *
- * If more than one ULID is generated within the same time, the random component
- * is incremented by one.
- *
- * @param time a given time
+ * @param time a number of milliseconds since 1970-01-01 (Unix epoch).
* @return a ULID
*/
public static Ulid getMonotonicUlid(final long time) {
diff --git a/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java b/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java
index 8aa53f6..ae98301 100644
--- a/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java
+++ b/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java
@@ -32,14 +32,19 @@ import java.util.function.LongFunction;
import java.util.function.LongSupplier;
/**
- * Factory that generates ULIDs.
- *
- * If the factory is not monotonic, the random component always changes.
- *
- * If the factory is monotonic, the random component changes whenever the
- * millisecond changes. If more than one ULID is generated within the same
- * millisecond, the random component is incremented by one.
- *
+ * A class that actually generates ULIDs.
+ *
+ * This class is used by {@link UlidCreator}.
+ *
+ * You can use this class if you need to use a specific random generator
+ * strategy. However, most people just need {@link UlidCreator}.
+ *
+ * Instances of this class can behave in one of two ways: monotonic or
+ * non-monotonic (default).
+ *
+ * If the factory is monotonic, the random component is incremented by 1 If more
+ * than one ULID is generated within the same millisecond.
+ *
* The maximum ULIDs that can be generated per millisecond is 2^80.
*/
public final class UlidFactory {
@@ -47,8 +52,15 @@ public final class UlidFactory {
private final Clock clock; // for tests
private final LongFunction
* It is equivalent to {@code new UlidFactory()}.
*
* @return {@link UlidFactory}
*/
public static UlidFactory newInstance() {
- return new UlidFactory(new UlidFunction());
+ return new UlidFactory(new UlidFunction(IRandom.newInstance()));
}
/**
@@ -78,31 +90,31 @@ public final class UlidFactory {
* @return {@link UlidFactory}
*/
public static UlidFactory newInstance(Random random) {
- return new UlidFactory(new UlidFunction(random));
+ return new UlidFactory(new UlidFunction(IRandom.newInstance(random)));
}
/**
* Returns a new factory.
- *
+ *
* The given random function must return a long value.
*
* @param randomFunction a random function that returns a long value
* @return {@link UlidFactory}
*/
public static UlidFactory newInstance(LongSupplier randomFunction) {
- return new UlidFactory(new UlidFunction(randomFunction));
+ return new UlidFactory(new UlidFunction(IRandom.newInstance(randomFunction)));
}
/**
* Returns a new factory.
- *
+ *
* The given random function must return a byte array.
*
* @param randomFunction a random function that returns a byte array
* @return {@link UlidFactory}
*/
public static UlidFactory newInstance(IntFunction
* The given random function must return a long value.
*
* @param randomFunction a random function that returns a long value
* @return {@link UlidFactory}
*/
public static UlidFactory newMonotonicInstance(LongSupplier randomFunction) {
- return new UlidFactory(new MonotonicFunction(randomFunction));
+ return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction)));
}
/**
* Returns a new monotonic factory.
- *
+ *
* The given random function must return a byte array.
*
* @param randomFunction a random function that returns a byte array
* @return {@link UlidFactory}
*/
public static UlidFactory newMonotonicInstance(IntFunction
* The given random function must return a long value.
*
* @param randomFunction a random function that returns a long value
* @param clock a custom clock instance for tests
* @return {@link UlidFactory}
*/
- protected static UlidFactory newMonotonicInstance(LongSupplier randomFunction, Clock clock) {
- return new UlidFactory(new MonotonicFunction(randomFunction), clock);
+ static UlidFactory newMonotonicInstance(LongSupplier randomFunction, Clock clock) {
+ return new UlidFactory(new MonotonicFunction(IRandom.newInstance(randomFunction)), clock);
}
/**
* Returns a new monotonic factory.
- *
+ *
* The given random function must return a byte array.
*
* @param randomFunction a random function that returns a byte array
* @param clock a custom clock instance for tests
* @return {@link UlidFactory}
*/
- protected static UlidFactory newMonotonicInstance(IntFunction
+ *
+ *