import static java.nio.charset.StandardCharsets.UTF_8;
+import java.nio.charset.Charset;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
* {@link Supplier#get()} method MUST be a v4 UUID (random).
*
* @see UUID
- * @see https://datatracker.ietf.org/doc/html/rfc4122
+ * @see "https://datatracker.ietf.org/doc/html/rfc4122"
*/
public interface UuidFactory extends Supplier<UUID> {
+
+ /*
+ * DEFAULT
+ */
+ /**
+ * The default {@link UUID} to provide, either random (v4) or time based (v1).
+ * It SHOULD wrap either {@link #timeUUID()} (recommended) or
+ * {@link #randomUUID()}.
+ */
+ @Override
+ UUID get();
+
/*
* TIME-BASED (version 1)
*/
+ /**
+ * A new time based {@link UUID} (v1) with efforts to make it unique on this
+ * node.
+ */
UUID timeUUID();
/*
* NAME BASED (version 3 and 5)
*/
+ /**
+ * A new {@link UUID} v5, which an SHA1 digest of namespace and the provided
+ * bytes. This use to build names and implementation MAY restrict the maximal
+ * size of the byte array.
+ *
+ * @see UuidFactory#NAMESPACE_UUID_DNS
+ * @see UuidFactory#NAMESPACE_UUID_URL
+ * @see UuidFactory#NAMESPACE_UUID_OID
+ * @see UuidFactory#NAMESPACE_UUID_X500
+ */
UUID nameUUIDv5(UUID namespace, byte[] data);
+ /**
+ * A new {@link UUID} v3, which a MD5 digest of namespace and the provided
+ * bytes. This use to build names and implementation MAY restrict the maximal
+ * size of the byte array.
+ *
+ * @see UuidFactory#NAMESPACE_UUID_DNS
+ * @see UuidFactory#NAMESPACE_UUID_URL
+ * @see UuidFactory#NAMESPACE_UUID_OID
+ * @see UuidFactory#NAMESPACE_UUID_X500
+ */
UUID nameUUIDv3(UUID namespace, byte[] data);
+ /**
+ * A convenience method to generate a name based UUID v5 based on a string,
+ * using the UTF-8 charset.
+ *
+ * @see UuidFactory#nameUUIDv5(UUID, byte[])
+ */
default UUID nameUUIDv5(UUID namespace, String name) {
+ return nameUUIDv5(namespace, name, UTF_8);
+ }
+
+ /**
+ * A convenience method to generate a name based UUID v5 based on a string.
+ *
+ * @see UuidFactory#nameUUIDv5(UUID, byte[])
+ */
+ default UUID nameUUIDv5(UUID namespace, String name, Charset charset) {
Objects.requireNonNull(name, "Name cannot be null");
- return nameUUIDv5(namespace, name.getBytes(UTF_8));
+ return nameUUIDv5(namespace, name.getBytes(charset));
}
+ /**
+ * A convenience method to generate a name based UUID v3 based on a string,
+ * using the UTF-8 charset.
+ *
+ * @see UuidFactory#nameUUIDv3(UUID, byte[])
+ */
default UUID nameUUIDv3(UUID namespace, String name) {
+ return nameUUIDv3(namespace, name, UTF_8);
+ }
+
+ /**
+ * A convenience method to generate a name based UUID v3 based on a string.
+ *
+ * @see UuidFactory#nameUUIDv3(UUID, byte[])
+ */
+ default UUID nameUUIDv3(UUID namespace, String name, Charset charset) {
Objects.requireNonNull(name, "Name cannot be null");
- return nameUUIDv3(namespace, name.getBytes(UTF_8));
+ return nameUUIDv3(namespace, name.getBytes(charset));
}
/*
* RANDOM (version 4)
*/
- /** A random UUID at least as good as {@link UUID#randomUUID()}. */
+ /**
+ * A random UUID at least as good as {@link UUID#randomUUID()}, but with efforts
+ * to make it even more random, using more secure algorithms and resseeding.
+ */
UUID randomUUIDStrong();
/**
/**
* The default random {@link UUID} (v4) generator to use. This default
- * implementation returns {@link #randomUUIDStrong()}.
+ * implementation returns {@link #randomUUIDStrong()}. In general, one should
+ * use {@link UUID#randomUUID()} to generate random UUID, as it is certainly the
+ * best balanced and to avoid unnecessary dependencies with an API. The
+ * implementations provided here are either when is looking for something
+ * "stronger" ({@link #randomUUIDStrong()} or faster {@link #randomUUIDWeak()}.
*/
default UUID randomUUID() {
return randomUUIDStrong();
}
- /**
- * The default {@link UUID} to provide, either random (v4) or time based (v1).
- * This default implementations returns {@link #randomUUID()}.
- */
- @Override
- default UUID get() {
- return randomUUID();
- }
-
/*
* STANDARD UUIDs
*/
* Standard DNS namespace ID for type 3 or 5 UUID (as defined in Appendix C of
* RFC4122).
*/
- final static UUID NS_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
+ final static UUID NAMESPACE_UUID_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
/**
* Standard URL namespace ID for type 3 or 5 UUID (as defined in Appendix C of
* RFC4122).
*/
- final static UUID NS_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
+ final static UUID NAMESPACE_UUID_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
/**
* Standard OID namespace ID (typically an LDAP type) for type 3 or 5 UUID (as
* defined in Appendix C of RFC4122).
*/
- final static UUID NS_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
+ final static UUID NAMESPACE_UUID_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
/**
* Standard X500 namespace ID (typically an LDAP DN) for type 3 or 5 UUID (as
* defined in Appendix C of RFC4122).
*/
- final static UUID NS_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8");
+ final static UUID NAMESPACE_UUID_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8");
/*
- * UTILITIES
+ * BIT LEVEL CONSTANTS
*/
+ /** Base for the most significant bit of version 1 (time based) UUIDs. */
+ long MOST_SIG_VERSION1 = (1l << 12);
+ /** Base for the least significant part of RFC4122 (variant 2) UUIDs. */
+ long LEAST_SIG_RFC4122_VARIANT = (1l << 63);
+ /*
+ * UTILITIES
+ */
+ /** Whether this {@link UUID} is random (v4). */
static boolean isRandom(UUID uuid) {
return uuid.version() == 4;
}
+ /** Whether this {@link UUID} is time based (v1). */
static boolean isTimeBased(UUID uuid) {
return uuid.version() == 1;
}
* Whether this UUID is time based but was not generated from an IEEE 802
* address, as per Section 4.5 of RFC4122.
*
- * @see https://datatracker.ietf.org/doc/html/rfc4122#section-4.5
+ * @see "https://datatracker.ietf.org/doc/html/rfc4122#section-4.5"
*/
static boolean isTimeBasedWithMacAddress(UUID uuid) {
if (uuid.version() == 1) {
return false;
}
+ /** Whether this {@link UUID} is name based (v3 or v5). */
static boolean isNameBased(UUID uuid) {
return uuid.version() == 3 || uuid.version() == 5;
}
+
+ /**
+ * The state of a time based UUID generator, as described and discussed in
+ * section 4.2.1 of RFC4122.
+ *
+ * @see "https://datatracker.ietf.org/doc/html/rfc4122#section-4.2.1"
+ */
+ interface TimeUuidState {
+ /** Current node id and clock sequence for this thread. */
+ long getLeastSignificantBits();
+
+ /** A new current timestamp for this thread. */
+ long getMostSignificantBits();
+
+ /**
+ * The last timestamp which was produced by this thread, as returned by
+ * {@link UUID#timestamp()}.
+ */
+ long getLastTimestamp();
+
+ /**
+ * The current clock sequence for this thread, as returned by
+ * {@link UUID#clockSequence()}.
+ */
+ long getClockSequence();
+ }
}