[java] JAVA에서 UUID 문자열을 생성하는 효율적인 방법 (대시없이 UUID.randomUUID (). toString ())

고유 한 바이트 시퀀스를 생성하는 효율적인 유틸리티를 원합니다. UUID는 좋은 후보이지만 좋은 것을 UUID.randomUUID().toString()생성 44e128a5-ac7a-4c9a-be4c-224b6bf81b20하지만 대시가없는 문자열을 선호합니다.

영숫자 문자 (대시 또는 다른 특수 기호 없음)에서만 무작위 문자열을 생성하는 효율적인 방법을 찾고 있습니다.



답변

이것은 그것을한다 :

public static void main(String[] args) {
    final String uuid = UUID.randomUUID().toString().replace("-", "");
    System.out.println("uuid = " + uuid);
}


답변

이 스레드의 URL에서 볼 수 있듯이 대시는 HTTP 요청에서 제거 할 필요가 없습니다. 그러나 데이터에 의존하지 않고 올바른 형식의 URL을 준비하려면 표준 데이터 형식을 변경하는 대신 URLEncoder.encode (String data, String encoding)를 사용해야합니다. UUID 문자열 표현의 경우 대시는 정상입니다.


답변

UUID.java 구현을 기반으로 내 자신의 무언가를 작성하게되었습니다. 내가있어주의 UUID를 생성하지 않음 , 대신 임의의 (32)는 내가 생각할 수있는 가장 효율적인 방법으로 16 진수 문자열을 바이트.

이행

import java.security.SecureRandom;
import java.util.UUID;

public class RandomUtil {
    // Maxim: Copied from UUID implementation :)
    private static volatile SecureRandom numberGenerator = null;
    private static final long MSB = 0x8000000000000000L;

    public static String unique() {
        SecureRandom ng = numberGenerator;
        if (ng == null) {
            numberGenerator = ng = new SecureRandom();
        }

        return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
    }
}

용법

RandomUtil.unique()

테스트

테스트를 거친 입력 중 일부가 작동하는지 확인했습니다.

public static void main(String[] args) {
    System.out.println(UUID.randomUUID().toString());
    System.out.println(RandomUtil.unique());

    System.out.println();
    System.out.println(Long.toHexString(0x8000000000000000L |21));
    System.out.println(Long.toBinaryString(0x8000000000000000L |21));
    System.out.println(Long.toHexString(Long.MAX_VALUE + 1));
}


답변

JUG (Java UUID Generator)를 사용하여 고유 ID를 생성했습니다. JVM에서 고유합니다. 사용하기에 좋습니다. 다음은 참조 용 코드입니다.

private static final SecureRandom secureRandom = new SecureRandom();
private static final UUIDGenerator generator = UUIDGenerator.getInstance();

public synchronized static String generateUniqueId() {
  UUID uuid = generator.generateRandomBasedUUID(secureRandom);

  return uuid.toString().replaceAll("-", "").toUpperCase();
}

https://github.com/cowtowncoder/java-uuid-generator 에서 라이브러리를 다운로드 할 수 있습니다.


답변

간단한 해결책은

UUID.randomUUID().toString().replace("-", "")

(기존의 솔루션과 마찬가지로 String # replaceAll 호출을 피할 수 있습니다. 여기에서는 정규식 대체가 필요하지 않으므로 기술적으로 여전히 정규식으로 구현되지만 String # replace 는 더 자연스럽게 느껴집니다. UUID 생성은 다음과 같습니다. 교체보다 비용이 많이 들지만 런타임에 큰 차이가 없어야합니다.)

UUID 클래스를 사용하는 것은 아마도 대부분의 시나리오에서 충분히 빠르지 만 후 처리가 필요없는 특수한 손으로 쓰는 변형이 더 빠를 것으로 기대합니다. 어쨌든 전체 계산의 병목 현상은 일반적으로 난수 생성기입니다. UUID 클래스의 경우 SecureRandom 을 사용합니다 .

어떤 난수 생성기를 사용할 것인지는 응용 프로그램에 따라 달라집니다. 보안에 민감한 경우 SecureRandom은 일반적으로 권장 사항입니다. 그렇지 않으면 ThreadLocalRandom 이 대안이 될 수 있습니다 (SecureRandom 또는 이전 Random 보다 빠르지 만 암호로 안전하지는 않음).


답변

나는 많은 문자열이 UUID의 아이디어를 대체하는 것을보고 놀랐습니다. 이건 어때요:

UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
     + Long.toHexString(temp.getLeastSignificantBits());

UUID의 전체 toString ()이 구문 분석 및 실행되거나 빈 문자열로 교체 해야하는 정규 표현식을 언급하지 않는 것이 더 비싸기 때문에 이것은 빠른 방법입니다.


답변

방금 UUID toString () 메서드를 복사하고 “-“를 제거하도록 업데이트했습니다. 다른 솔루션보다 훨씬 빠르고 간단합니다.

public String generateUUIDString(UUID uuid) {
    return (digits(uuid.getMostSignificantBits() >> 32, 8) +
            digits(uuid.getMostSignificantBits() >> 16, 4) +
            digits(uuid.getMostSignificantBits(), 4) +
            digits(uuid.getLeastSignificantBits() >> 48, 4) +
            digits(uuid.getLeastSignificantBits(), 12));
}

/** Returns val represented by the specified number of hex digits. */
private String digits(long val, int digits) {
    long hi = 1L << (digits * 4);
    return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}

용법:

generateUUIDString(UUID.randomUUID())

리플렉션을 사용한 또 다른 구현

public String generateString(UUID uuid) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    if (uuid == null) {
        return "";
    }

    Method digits = UUID.class.getDeclaredMethod("digits", long.class, int.class);
    digits.setAccessible(true);

    return ( (String) digits.invoke(uuid, uuid.getMostSignificantBits() >> 32, 8) +
            digits.invoke(uuid, uuid.getMostSignificantBits() >> 16, 4) +
            digits.invoke(uuid, uuid.getMostSignificantBits(), 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits() >> 48, 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits(), 12));

}