gpt4 book ai didi

java - 如何在 Java 中复制 PostgreSQL 的 uuid_generate_v3()?

转载 作者:行者123 更新时间:2023-11-29 14:18:14 25 4
gpt4 key购买 nike

PostgreSQL:

 create extension if not exists "uuid-ossp";
select uuid_generate_v3(uuid_nil(), 'this is a test');
uuid_generate_v3
--------------------------------------
e1e27115-9f5b-366d-90e8-e07b1b36b99c
(1 row)

Java:

java> java.util.UUID.nameUUIDFromBytes("this is a test".getBytes());
java.util.UUID res9 = 54b0c58c-7ce9-32a8-b551-351102ee0938

如何在 Java 中生成与 PostgreSQL 相同的 UUID?

最佳答案

此处描述了生成版本 3 UUID 的算法 https://www.rfc-editor.org/rfc/rfc4122#section-4.3

但关键步骤是:

  • 分配一个 UUID 用作所有 UUID 的“ namespace ID”从该 namespace 中的名称生成。
  • 选择 MD5 或 SHA-1 作为哈希算法
  • 将名称转换为规范的八位字节序列
  • 计算与名称连接的 namespace ID 的哈希值。
  • 将 的某些字节更改为预定义值(参见上面的链接)
  • 将生成的 UUID 转换为本地字节顺序。

postgres 函数签名是 uuid_generate_v3(namespace uuid, name text) 所以它以命名空间 UUID 和 name 作为参数。
Java 方法 nameUUIDFromBytes(byte[] name) 仅采用 name 并使用 MD5 对其进行哈希处理以创建 UUID。要获得与 PostgreSQL 相同的输出,您必须自己将命名空间字节和 name 字节连接在一起。

对于命名空间,您使用了 uuid_nil()(全为零),它是 Java 中的 new UUID(0L, 0L)

将它们放在一起看起来像这样:

byte[] bytes = Arrays.concatenate(toByteArray(new UUID(0L, 0L)), "this is a test".getBytes(StandardCharsets.UTF_8));
System.out.println(UUID.nameUUIDFromBytes(bytes)); // prints out e1e27115-9f5b-366d-90e8-e07b1b36b99c

您可以像这样将命名空间 UUID 转换为字节数组:

private static byte[] toByteArray(UUID uuid) {
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return bb.array();
}

关于java - 如何在 Java 中复制 PostgreSQL 的 uuid_generate_v3()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40616100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com