有什么方法可以从 String 生成相同的 UUID

新手上路,请多包涵

我想知道是否有一种方法可以基于 String. 我试过使用 UUID,看起来它不提供此功能。

原文由 Adam Lee 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 713
2 个回答

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

  String aString="JUST_A_TEST_STRING";
 String result = UUID.nameUUIDFromBytes(aString.getBytes()).toString();

原文由 uraimo 发布,翻译遵循 CC BY-SA 3.0 许可协议

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)));
    }
}

这是输出:

 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'

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

 // Create a UUIDv5 (SHA1)
String name = "JUST_A_TEST_STRING";
UUID uuid = UuidCreator.getNameBasedSha1(name);

原文由 fabiolimace 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题