programing

문자열에서 동일한 UUID를 생성할 수 있는 방법이 있습니까?

goodjava 2023. 1. 4. 20:03

문자열에서 동일한 UUID를 생성할 수 있는 방법이 있습니까?

같은 UUID를 생성할 수 있는 방법이 있을까요?String.UUID로 시도했는데 이 기능은 제공되지 않는 것 같습니다.

이 방법으로 UUID를 사용하면 입력 문자열에 대해 항상 동일한 UUID를 얻을 수 있습니다.

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

UUID.nameUUIDFromBytes()메서드는 MD5 UUID를 생성합니다.이전 버전과의 호환성이 문제가 되지 않는 경우 MD5보다 SHA1이 우선됩니다.

이것은 MD5 및 SHA1 UUID를 생성하는 유틸리티 클래스입니다.또한 네임스페이스도 지원합니다.UUID.nameUUIDFromBytes()RFC-4122에서는 필요하지만 메서드는 지원하지 않습니다.자유롭게 사용하고 공유하세요.

package com.example;

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

/**
 * Utility class that creates UUIDv3 (MD5) and UUIDv5 (SHA1).
 *
 * It is fully compliant with RFC-4122.
 */
public class HashUuidCreator {

    // Domain Name System
    public static final UUID NAMESPACE_DNS = new UUID(0x6ba7b8109dad11d1L, 0x80b400c04fd430c8L);
    // Uniform Resource Locator
    public static final UUID NAMESPACE_URL = new UUID(0x6ba7b8119dad11d1L, 0x80b400c04fd430c8L);
    // ISO Object ID
    public static final UUID NAMESPACE_ISO_OID = new UUID(0x6ba7b8129dad11d1L, 0x80b400c04fd430c8L);
    // X.500 Distinguished Name
    public static final UUID NAMESPACE_X500_DN = new UUID(0x6ba7b8149dad11d1L, 0x80b400c04fd430c8L);

    private static final int VERSION_3 = 3; // UUIDv3 MD5
    private static final int VERSION_5 = 5; // UUIDv5 SHA1

    private static final String MESSAGE_DIGEST_MD5 = "MD5"; // UUIDv3
    private static final String MESSAGE_DIGEST_SHA1 = "SHA-1"; // UUIDv5

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

        final byte[] hash;
        final MessageDigest hasher;

        try {
            // Instantiate a message digest for the chosen algorithm
            hasher = MessageDigest.getInstance(algorithm);

            // Insert name space if NOT NULL
            if (namespace != null) {
                hasher.update(toBytes(namespace.getMostSignificantBits()));
                hasher.update(toBytes(namespace.getLeastSignificantBits()));
            }

            // Generate the hash
            hash = hasher.digest(name.getBytes(StandardCharsets.UTF_8));

            // Split the hash into two parts: MSB and LSB
            long msb = toNumber(hash, 0, 8); // first 8 bytes for MSB
            long lsb = toNumber(hash, 8, 16); // last 8 bytes for LSB

            // Apply version and variant bits (required for RFC-4122 compliance)
            msb = (msb & 0xffffffffffff0fffL) | (version & 0x0f) << 12; // apply version bits
            lsb = (lsb & 0x3fffffffffffffffL) | 0x8000000000000000L; // apply variant bits

            // Return the UUID
            return new UUID(msb, lsb);

        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Message digest algorithm not supported.");
        }
    }

    public static UUID getMd5Uuid(String string) {
        return getHashUuid(null, string, MESSAGE_DIGEST_MD5, VERSION_3);
    }

    public static UUID getSha1Uuid(String string) {
        return getHashUuid(null, string, MESSAGE_DIGEST_SHA1, VERSION_5);
    }

    public static UUID getMd5Uuid(UUID namespace, String string) {
        return getHashUuid(namespace, string, MESSAGE_DIGEST_MD5, VERSION_3);
    }

    public static UUID getSha1Uuid(UUID namespace, String string) {
        return getHashUuid(namespace, string, MESSAGE_DIGEST_SHA1, VERSION_5);
    }

    private static byte[] toBytes(final long number) {
        return new byte[] { (byte) (number >>> 56), (byte) (number >>> 48), (byte) (number >>> 40),
                (byte) (number >>> 32), (byte) (number >>> 24), (byte) (number >>> 16), (byte) (number >>> 8),
                (byte) (number) };
    }

    private static long toNumber(final byte[] bytes, final int start, final int length) {
        long result = 0;
        for (int i = start; i < length; i++) {
            result = (result << 8) | (bytes[i] & 0xff);
        }
        return result;
    }

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

        String string = "JUST_A_TEST_STRING";
        UUID namespace = UUID.randomUUID(); // A custom name space

        System.out.println("Java's generator");
        System.out.println("UUID.nameUUIDFromBytes():      '" + UUID.nameUUIDFromBytes(string.getBytes()) + "'");
        System.out.println();
        System.out.println("This generator");
        System.out.println("HashUuidCreator.getMd5Uuid():  '" + HashUuidCreator.getMd5Uuid(string) + "'");
        System.out.println("HashUuidCreator.getSha1Uuid(): '" + HashUuidCreator.getSha1Uuid(string) + "'");
        System.out.println();
        System.out.println("This generator WITH name space");
        System.out.println("HashUuidCreator.getMd5Uuid():  '" + HashUuidCreator.getMd5Uuid(namespace, string) + "'");
        System.out.println("HashUuidCreator.getSha1Uuid(): '" + HashUuidCreator.getSha1Uuid(namespace, string) + "'");
    }
}

출력은 다음과 같습니다.

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

// This generator
HashUuidCreator.getMd5Uuid():  '9e120341-627f-32be-8393-58b5d655b751'
HashUuidCreator.getSha1Uuid(): 'e4586bed-032a-5ae6-9883-331cd94c4ffa'

// This generator WITH name space (as the standard requires)
HashUuidCreator.getMd5Uuid():  '2b098683-03c9-3ed8-9426-cf5c81ab1f9f'
HashUuidCreator.getSha1Uuid(): '1ef568c7-726b-58cc-a72a-7df173463bbb'

를 사용할 수도 있습니다.uuid-creator도서관.다음의 예를 참조해 주세요.

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

프로젝트 페이지: https://github.com/f4b6a3/uuid-creator

UUID v5를 사용해야 합니다.

버전 3 및 버전5 UUID는 네임스페이스 ID와 이름을 해시함으로써 생성됩니다.버전 3은 해싱 알고리즘으로 MD5를 사용하고 버전5는 SHA-1.1 - wikipedia를 사용합니다.

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>

다음과 같이 사용할 수 있습니다.

UUID namespace = ; // todo generate a UUID v4.
String input = "input";
UUID uuid = UuidCreator.getNameBasedSha1(namespace, input);

(어떤 면에서는 네임스페이스는 난수 생성기의 시드처럼 동작합니다.반면 시드는 랜덤이지만 네임스페이스는 상수입니다.그 때문에, 델의 발전기는, 특정의 입력에 대해서 항상 같은 값을 생성하게 됩니다.)

Javascript 대체를 찾고 있는 경우 문자열별 uuid를 참조하십시오.이 uid는 SHA-1 또는 MD5 해시함수를 사용하는 옵션도 제공합니다.

언급URL : https://stackoverflow.com/questions/29059530/is-there-any-way-to-generate-the-same-uuid-from-a-string