Java UUID 生成器示例

Java UUID 生成器示例

原文: https://howtodoinjava.com/java/basics/java-uuid/

了解什么是 UUID 及其版本和变体。 学习使用UUID.randomUUID() API 在 Java 中生成 UUID。 另请学习用 Java 生成版本 5 UUID。

1. 什么是 UUID?

UUID通用唯一标识符),也称为 GUID全局唯一标识符)是128 bits长标识符,相对于所有其他 UUID 的空间而言。 它不需要中央注册过程。 结果,按需生成可以完全自动化,并用于多种目的。

要了解 UUID 的独特性,您应该知道 UUID 生成算法支持非常高的分配速率,每台机器每秒可支持高达 1000 万的速度,因此甚至可以用作事务 ID。

我们可以应用排序,排序并将它们存储在数据库中。 通常,它在编程中很有用。

由于 UUID 是唯一且持久的,因此与其他替代方法相比,它们具有出色的统一资源名称(URN),挖掘成本最低。

空的 UUID(UHTID)是 UUID 的一种特殊形式,它指定将所有 128 位都设置为零。

不要以为 UUID 很难猜测; 它们不应用作安全特性。 可预测的随机数源将加剧这种情况。 人类没有能力仅仅看一眼就能轻易地检查 UUID 的完整性。

2. UUID 类型

典型的 UUID 以8-4-4-4-12的形式显示在 5 组中,由连字符分隔,总共 36 个字符(32 个字母数字字符和 4 个连字符)。

123e4567-e89b-12d3-a456-426655440000

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

在此'M'表示 UUID 版本'N'表示 UUID 变体

  • 变体字段包含一个值,该值标识 UUID 的布局。
  • 版本字段包含一个描述此 UUID 类型的值。 UUID 有五种不同的基本类型。
    1. 基于时间的 UUID(版本 1) – 根据时间和节点 ID 生成
    2. DCE(分布式计算环境)安全性(版本 2) – 由标识符(通常是组或用户 ID),时间和节点 ID 生成
    3. 基于名称(版本 3) – 由 MD5 (128 位)的名称空间标识符和名称的哈希值生成
    4. 随机生成的 UUID(版本 4) – 使用随机或伪随机数生成
    5. 基于名称的使用 SHA-1 哈希(版本 5)推荐的 – 由 SHA-1 (160 位)哈希处理的名称空间标识符和名称。 Java 不提供其实现。 我们将创造自己的。

3. Java UUID 示例

3.1 UUID.randomUUID() – 版本 4

默认 API randomUUID()是一个静态工厂,用于检索类型 4(伪随机生成的)UUID。 对于大多数用例来说已经足够了。

UUID uuid = UUID.randomUUID();

System.out.println(uuid);
System.out.println(uuid.variant());		//2
System.out.println(uuid.version());		//4

程序输出。

17e3338d-344b-403c-8a87-f7d8006d6e33
2
4

3.2 生成版本 5 UUID

Java 没有提供内置 API 来生成版本 5 UUID,因此我们必须创建自己的实现。 以下是一种这样的实现。 (参考)。

import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

public class UUID5 
{
	public static UUID fromUTF8(String name) {
		return fromBytes(name.getBytes(Charset.forName("UTF-8")));
	}

	private static UUID fromBytes(byte[] name) {
		if (name == null) {
			throw new NullPointerException("name == null");
		}
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			return makeUUID(md.digest(name), 5);
		} catch (NoSuchAlgorithmException e) {
			throw new AssertionError(e);
		}
	}

	private static UUID makeUUID(byte[] hash, int version) {
		long msb = peekLong(hash, 0, ByteOrder.BIG_ENDIAN);
		long lsb = peekLong(hash, 8, ByteOrder.BIG_ENDIAN);
		// Set the version field
		msb &= ~(0xfL << 12);
		msb |= ((long) version) << 12;
		// Set the variant field to 2
		lsb &= ~(0x3L << 62);
		lsb |= 2L << 62;
		return new UUID(msb, lsb);
	}

	private static long peekLong(final byte[] src, final int offset, final ByteOrder order) {
		long ans = 0;
		if (order == ByteOrder.BIG_ENDIAN) {
			for (int i = offset; i < offset + 8; i += 1) {
				ans <<= 8;
				ans |= src[i] & 0xffL;
			}
		} else {
			for (int i = offset + 7; i >= offset; i -= 1) {
				ans <<= 8;
				ans |= src[i] & 0xffL;
			}
		}
		return ans;
	}
}

UUID uuid = UUID5.fromUTF8("954aac7d-47b2-5975-9a80-37eeed186527");

System.out.println(uuid);
System.out.println(uuid.variant());
System.out.println(uuid.version());

d1d16b54-9757-5743-86fa-9ffe3b937d78
2
5

向我提供有关在 Java 中生成 UUID 的问题。

学习愉快!

参考: Rfc 4122