IT지식

String to UUID/ UUID to String

오선지♬ 2024. 8. 4. 12:07
728x90
반응형
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

public class UUIDExample {
    public static void main(String[] args) {
        // 숫자 ID를 문자열로 변환
        String name = "128478";
        
        // 네임스페이스 UUID (예: URL 네임스페이스)
        UUID namespace = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); // URL 네임스페이스

        // UUID 버전 3 생성 (MD5 해시 사용)
        UUID uuidV3 = generateUUIDv3(namespace, name);
        System.out.println("UUID 버전 3: " + uuidV3);

        // UUID 버전 5 생성 (SHA-1 해시 사용)
        UUID uuidV5 = generateUUIDv5(namespace, name);
        System.out.println("UUID 버전 5: " + uuidV5);
    }

    public static UUID generateUUIDv3(UUID namespace, String name) {
        return generateUUID(namespace, name, "MD5");
    }

    public static UUID generateUUIDv5(UUID namespace, String name) {
        return generateUUID(namespace, name, "SHA-1");
    }

    private static UUID generateUUID(UUID namespace, String name, String algorithm) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            md.update(toBytes(namespace));
            md.update(name.getBytes(StandardCharsets.UTF_8));
            byte[] hash = md.digest();
            long msb = bytesToLong(hash, 0);
            long lsb = bytesToLong(hash, 8);
            msb = (msb & 0xFFFFFFFFFFFF0FFFL) | (algorithm.equals("MD5") ? 0x3000 : 0x5000);
            lsb = (lsb & 0x3FFFFFFFFFFFFFFFL) | 0x8000000000000000L;
            return new UUID(msb, lsb);
        } catch (No

 

이와 같은 방식으로 기존의 숫자 ID를 기반으로 고유한 UUID를 생성할 수 있습니다. 다만, 주의할 점은 생성된 UUID는 원본 ID를 직접 나타내는 것은 아니며, 단순히 해당 ID를 기반으로 유일한 식별자를 생성한 것일 뿐입니다.

 

 

변환한 UUID를 다시 문자열로 변환하는 것은 매우 간단합니다. 자바의 java.util.UUID 클래스는 toString() 메서드를 제공하여 UUID 객체를 문자열로 변환할 수 있습니다. 이 메서드는 UUID를 표준 형식(8-4-4-4-12)으로 된 32자리 16진수 문자열로 반환합니다.

아래는 UUID를 문자열로 변환하는 방법을 포함한 코드 예제입니다.

 

 

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

public class UUIDExample {
    public static void main(String[] args) {
        // 숫자 ID를 문자열로 변환
        String name = "128478";
        
        // 네임스페이스 UUID (예: URL 네임스페이스)
        UUID namespace = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); // URL 네임스페이스

        // UUID 버전 3 생성 (MD5 해시 사용)
        UUID uuidV3 = generateUUIDv3(namespace, name);
        System.out.println("UUID 버전 3: " + uuidV3.toString()); // UUID를 문자열로 변환하여 출력

        // UUID 버전 5 생성 (SHA-1 해시 사용)
        UUID uuidV5 = generateUUIDv5(namespace, name);
        System.out.println("UUID 버전 5: " + uuidV5.toString()); // UUID를 문자열로 변환하여 출력
    }

    public static UUID generateUUIDv3(UUID namespace, String name) {
        return generateUUID(namespace, name, "MD5");
    }

    public static UUID generateUUIDv5(UUID namespace, String name) {
        return generateUUID(namespace, name, "SHA-1");
    }

    private static UUID generateUUID(UUID namespace, String name, String algorithm) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            md.update(toBytes(namespace));
            md.update(name.getBytes(StandardCharsets.UTF_8));
            byte[] hash = md.digest();
            long msb = bytesToLong(hash, 0);
            long lsb = bytesToLong(hash, 8);
            msb = (msb & 0xFFFFFFFFFFFF0FFFL) | (algorithm.equals("MD5") ? 0x3000 : 0x5000);
            lsb = (lsb & 0x3FFFFFFFFFFFFFFFL) | 0x8000000000000000L;
            return new UUID(msb, lsb);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    private static byte[] toBytes(UUID uuid) {
        byte[] bytes = new byte[16];
        long msb = uuid.getMostSignificantBits();
        long lsb = uuid.getLeastSignificantBits();
        for (int i = 0; i < 8; i++) {
            bytes[i] = (byte) (msb >>> (8 * (7 - i)));
            bytes[8 + i] = (byte) (lsb >>> (8 * (7 - i)));
        }
        return bytes;
    }

    private static long bytesToLong(byte[] bytes, int offset) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value = (value << 8) | (bytes[offset + i] & 0xFF);
        }
        return value;
    }
}

 

 

UUID에서 원래의 문자열("128478")로 직접 변환하는 것은 불가능합니다. UUID는 주어진 이름(이 경우 "128478")을 기반으로 고유한 식별자를 생성하기 위해 해시 알고리즘을 사용합니다. 이 과정에서 해시 함수는 단방향 함수로 작동하기 때문에, 원본 데이터를 다시 얻을 수 없습니다. 즉, 해시된 결과에서 원래의 입력 값을 역추적하는 것은 설계상 불가능합니다.

하지만, 특정 상황에서는 UUID를 생성한 후 원본 데이터를 저장해두는 방법으로 원래 문자열과 매핑할 수 있습니다. 예를 들어, UUID와 원래 문자열을 데이터베이스에 함께 저장해 두었다가 나중에 UUID를 기반으로 원본 문자열을 조회할 수 있습니다.

예제: UUID와 원본 문자열 저장 및 조회

  1. 데이터 저장:
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class UUIDStore {
    private static Map<UUID, String> uuidToStringMap = new HashMap<>();

    public static void main(String[] args) {
        String name = "128478";
        UUID uuid = UUID.nameUUIDFromBytes(name.getBytes());

        // UUID와 원본 문자열을 매핑
        uuidToStringMap.put(uuid, name);

        System.out.println("Generated UUID: " + uuid);
        System.out.println("Original string: " + name);
    }

    public static String getStringFromUUID(UUID uuid) {
        return uuidToStringMap.get(uuid);
    }
}

 

2.데이터 조회:

UUID storedUUID = ...; // 저장된 UUID
String originalString = UUIDStore.getStringFromUUID(storedUUID);
System.out.println("Original string: " + originalString);

 

이 예제에서는 UUIDStore 클래스가 UUID와 원본 문자열을 저장하고, UUID를 사용해 원본 문자열을 조회할 수 있는 기능을 제공합니다. 이 방법을 통해 "128478"과 같은 원본 데이터를 나중에 다시 조회할 수 있습니다.

중요한 사항

해시 알고리즘의 목적은 보안과 데이터의 무결성을 보장하는 것이지, 데이터를 복원하는 것이 아닙니다. 따라서 해시 함수는 원래 데이터로의 변환이 불가능하도록 설계되었습니다. 만약 원래 데이터를 반드시 복원해야 하는 경우, 데이터를 저장하거나 별도로 관리하는 방법을 고려해야 합니다.

728x90
반응형

'IT지식' 카테고리의 다른 글

[Eclipse] 자동완성 기능 활성  (0) 2024.08.23
UTC란  (0) 2024.08.17
[Eclipse] Gradle과 "Add Spring Project Nature"의 관계  (0) 2024.08.03
[Eclipse] 이클립스 - Spring > Add Spring Project Nature  (0) 2024.08.02
Ai 파일 vs JPG 파일  (0) 2024.08.01