JDK 使用什么命名空间来生成具有 nameUUIDFromBytes 的 UUID?

2022-09-04 03:36:24

Sun/Oracle JDK 公开了一个函数,用于在 java.util 包中创建类型 3(基于名称)UUID:java.util.UUID.nameUUIDFromBytes(byte[] name)。

我需要能够使用nameUUIDFromBytes在Java中生成3类UUID,并在用另一种语言创建类型3 UUID时到达相同的UUID,假设我提供与源相同的字节。

根据javadocs,此函数创建符合RFC 4122的类型3 UUID。但是,根据 RFC 4122 规范,必须在某个命名空间中创建类型 3 UUID。大多数其他语言允许您在创建类型 3 UUID 时指定命名空间(例如,Ruby 中的 UUIDTools gem)。

所以我的问题是:当我调用nameUUIDFromBytes时,JDK使用什么命名空间UUID?


答案 1

请参阅此错误报告

特别是靠近底部的评论:

也许此时的操作过程是修复javadoc,指出“nameUUIDFromBytes(byte[] namespaceAndName)”应该传入一个字节数组,其中包含命名空间UUID的字节和名称字节的串联(按该顺序)“,这假设该方法只是MD5的byte[],并根据IETF文档设置字段。

我不知道我是否相信这可以正常工作,但是使用UUID规范中的预定义名称规范进行测试应该很容易,与其他一些实现生成的相同UUID进行比较。

[Edit 2022-05-22:修复了指向工作Java错误数据库的链接,尽管新的错误数据库不包括以前数据库的评论,特别是本答案中引用的评论]


答案 2

示例代码:

String NameSpace_OID_string = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
UUID NameSpace_OID_uuid = UUID.fromString(NameSpace_OID_string);

long msb = NameSpace_OID_uuid.getMostSignificantBits();
long lsb = NameSpace_OID_uuid.getLeastSignificantBits();

    byte[] NameSpace_OID_buffer = new byte[16];

    for (int i = 0; i < 8; i++) {
        NameSpace_OID_buffer[i] = (byte) (msb >>> 8 * (7 - i));
    }
    for (int i = 8; i < 16; i++) {
        NameSpace_OID_buffer[i] = (byte) (lsb >>> 8 * (7 - i));
    }

    String name = "user123";
    byte[] name_buffer = name.getBytes();

ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
try {
    outputStream.write( NameSpace_OID_buffer);
    outputStream.write( name_buffer );
} catch (IOException e) {
        // TODO Auto-generated catch block
    e.printStackTrace();
}


byte byteArray[] = outputStream.toByteArray();

System.out.println(UUID.nameUUIDFromBytes(byteArray).toString());