有没有办法从String生成相同的UUID

Ada*_*Lee 44 java uuid

我想知道是否有一种方法可以根据String. 我尝试使用UUID 生成相同的UUID,看起来它不提供此功能.

Umb*_*ndi 96

您可以通过这种方式使用UUID为输入字符串获取始终相同的UUID:

 String aString="JUST_A_TEST_STRING";
 String result = UUID.nameUUIDFromBytes(aString.getBytes()).toString();
Run Code Online (Sandbox Code Playgroud)

  • 从给定字符串生成的 UUID 与从另一个字符串生成的 UUID 发生冲突的可能性有多大? (4认同)
  • 有什么办法可以将此 UUID 解码为原始 String 吗? (3认同)
  • 任何js等效? (2认同)
  • @mika [这个 PHP UUID 库](https://github.com/ramsey/uuid) 有点等价。您可以为给定的命名空间 + 字符串生成相同的 UUID。你可以这样做: `Uuid::uuid3(Uuid::NAMESPACE_DNS, 'TEST STRING')->toString();` 在这个例子中它使用 md5 散列。[关于 UUID 命名空间的附加信息](/sf/answers/2014381631/) (2认同)
  • 如果原始字符串是已知字符串集的一部分(例如存储在数据库中),您可以为每个字符串生成 UUID 并与要解码的 UUID 进行比较。否则,“技术上”是不可能的 (2认同)

fab*_*ace 19

UUID.nameUUIDFromBytes()仅生成 MD5 UUID。但是,如果向后兼容性不是问题,SHA1 优于 MD5 。

下面的实用程序类生成 MD5 UUID 和 SHA-1 UUID。欢迎使用和分享。

package com.example;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * Generates UUIDv3 (MD5) and UUIDv5 (SHA1).
 *
 * It is fully compliant with RFC-4122.
 */
public class HashUuid {

    private static final int V3 = 3; // MD5
    private static final int V5 = 5; // SHA-1

    private static final String HASH_V3 = "MD5";
    private static final String HASH_V5 = "SHA-1";

    public static final UUID NAMESPACE_DNS = new UUID(0x6ba7b8109dad11d1L, 0x80b400c04fd430c8L);
    public static final UUID NAMESPACE_URL = new UUID(0x6ba7b8119dad11d1L, 0x80b400c04fd430c8L);
    public static final UUID NAMESPACE_OID = new UUID(0x6ba7b8129dad11d1L, 0x80b400c04fd430c8L);
    public static final UUID NAMESPACE_X500 = new UUID(0x6ba7b8149dad11d1L, 0x80b400c04fd430c8L);

    public static UUID v3(String name) {
        return generate(V3, HASH_V3, null, name);
    }

    public static UUID v5(String name) {
        return generate(V5, HASH_V5, null, name);
    }

    public static UUID v3(UUID namespace, String name) {
        return generate(V3, HASH_V3, namespace, name);
    }

    public static UUID v5(UUID namespace, String name) {
        return generate(V5, HASH_V5, namespace, name);
    }

    private static UUID generate(int version, String algorithm, UUID namespace, String name) {

        MessageDigest hasher = hasher(algorithm);

        if (namespace != null) {
            ByteBuffer ns = ByteBuffer.allocate(16);
            ns.putLong(namespace.getMostSignificantBits());
            ns.putLong(namespace.getLeastSignificantBits());
            hasher.update(ns.array());
        }

        hasher.update(name.getBytes(StandardCharsets.UTF_8));
        ByteBuffer hash = ByteBuffer.wrap(hasher.digest());

        final long msb = (hash.getLong() & 0xffffffffffff0fffL) | (version & 0x0f) << 12;
        final long lsb = (hash.getLong() & 0x3fffffffffffffffL) | 0x8000000000000000L;

        return new UUID(msb, lsb);
    }

    private static MessageDigest hasher(String algorithm) {
        try {
            return MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(String.format("%s not supported.", algorithm));
        }
    }

    /**
     * For tests!
     */
    public static void main(String[] args) {

        UUID namespace = UUID.randomUUID();
        String name = "JUST_A_TEST_STRING";

        System.out.println(String.format("UUID.nameUUIDFromBytes():     '%s'", UUID.nameUUIDFromBytes(name.getBytes())));
        System.out.println();
        System.out.println(String.format("HashUuid.v3(name):            '%s'", HashUuid.v3(name)));
        System.out.println(String.format("HashUuid.v5(name):            '%s'", HashUuid.v5(name)));
        System.out.println(String.format("HashUuid.v3(namespace, name): '%s'", HashUuid.v3(namespace, name)));
        System.out.println(String.format("HashUuid.v5(namespace, name): '%s'", HashUuid.v5(namespace, name)));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

UUID.nameUUIDFromBytes():     '9e120341-627f-32be-8393-58b5d655b751'

HashUuid.v3(name):            '9e120341-627f-32be-8393-58b5d655b751'
HashUuid.v5(name):            'e4586bed-032a-5ae6-9883-331cd94c4ffa'
HashUuid.v3(namespace, name): 'f0043437-723b-308f-a6c0-74ec36ddf9c2'
HashUuid.v5(namespace, name): '18a45fd8-8fab-5647-aad7-1d3264932180'
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用uuid-creator. 看这个例子:

UUID.nameUUIDFromBytes():     '9e120341-627f-32be-8393-58b5d655b751'

HashUuid.v3(name):            '9e120341-627f-32be-8393-58b5d655b751'
HashUuid.v5(name):            'e4586bed-032a-5ae6-9883-331cd94c4ffa'
HashUuid.v3(namespace, name): 'f0043437-723b-308f-a6c0-74ec36ddf9c2'
HashUuid.v5(namespace, name): '18a45fd8-8fab-5647-aad7-1d3264932180'
Run Code Online (Sandbox Code Playgroud)


bvd*_*vdb 8

您应该使用UUID v5。

版本 3 和版本 5 UUID 是通过对命名空间标识符和名称进行哈希处理生成的。版本 3 使用 MD5 作为哈希算法,版本 5 使用 SHA-1。1 -维基百科

UUID v5 需要命名空间。该命名空间应该是 UUID v4,您可以在线生成它。命名空间确保对于给定的输入,输出始终相同。

UUID v5 的可能实现可以在这里找到:

<!-- https://search.maven.org/artifact/com.github.f4b6a3/uuid-creator -->
<dependency>
  <groupId>com.github.f4b6a3</groupId>
  <artifactId>uuid-creator</artifactId>
  <version>3.6.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

它可以按如下方式使用:

UUID namespace = ; // todo generate a UUID v4.
String input = "input";
UUID uuid = UuidCreator.getNameBasedSha1(namespace, input);
Run Code Online (Sandbox Code Playgroud)

(在某种程度上,命名空间的作用就像随机数生成器的种子一样。相比之下,虽然种子应该是随机的,但我们的命名空间是一个常量。这迫使我们的生成器始终为给定输入。)