如何在 Java 中复制 PostgreSQL 的 uuid_generate_v3()? [英] How do I replicate PostgreSQL's uuid_generate_v3() in Java?

查看:27
本文介绍了如何在 Java 中复制 PostgreSQL 的 uuid_generate_v3()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PostgreSQL:

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?

How do I generate the same UUID's in Java as PostgreSQL does?

推荐答案

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

The algorithm for generating a version 3 UUID is described here https://tools.ietf.org/html/rfc4122#section-4.3

但关键步骤是:

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

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

The postgres function signature is uuid_generate_v3(namespace uuid, name text) so it takes the namespace UUID and name as arguments.
The Java method nameUUIDFromBytes(byte[] name) takes only the name and hashes it with MD5 to create the UUID. To get the same output as with PostgreSQL you have to concatenate the the namespace bytes and the name bytes together yourself.

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

For namespace you have used uuid_nil() (all zeroes) which is new UUID(0L, 0L) in Java.

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

Putting it all together this would look something like this:

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 转换为字节数组:

And you can convert the namespace UUID to byte array like so:

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 中复制 PostgreSQL 的 uuid_generate_v3()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆