Java UUID生成器示例

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

1.什么是UUID?

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

要了解UUID的独特性,您应该知道UUID生成算法在必要时支持非常高的分配速率,每台计算机每秒高达1000万,这样它们甚至可以用作事务ID。

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

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

零UUID是UUID的特殊形式被指定为具有所有128位设置为零。

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

2。 UUID类型

典型的UID按5个组显示,由连字符分隔,格式为8-4-4-4-12,共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

saigon has written 1445 articles

Leave a Reply