Java에서 가장 중요한 UUID 비트를 사용하는 충돌 가능성

긴 uuid = UUID.randomUUID().getMostSignificantBits()`를 사용하는 경우 충돌이 발생할 가능성이 얼마나됩니까? 최하위 비트를 잘라내므로 충돌이 발생할 가능성이 있겠죠?

해결책

문서]1에 따르면 정적 메서드 UUID.randomUUID()는 유형 4 UUID를 생성합니다.

즉, 일부 유형 정보에 6비트가 사용되고 나머지 122비트는 무작위로 할당됩니다.

무작위가 아닌 6개의 비트는 UUID의 가장 중요한 절반에 4개, 가장 중요하지 않은 절반에 2개로 분배됩니다. 따라서 UUID의 가장 중요한 절반에는 60비트의 무작위성이 포함되어 있으므로 충돌을 일으키려면 평균적으로 2^30개의 UUID를 생성해야 합니다(전체 UUID의 경우 2^61개에 비해).

따라서 다소 안전하다고 말할 수 있습니다. 하지만 칼 셀레보그가 언급했듯이 다른 유형의 UUID에서는 절대 그렇지 않다는 점에 유의하세요.

덧붙여서, UUID의 최하위 절반을 사용하거나 SecureRandom을 사용하여 임의의 긴 값을 생성하는 것이 약간 더 나을 수 있습니다.

해설 (3)

레이몬드 첸이 이에 대한 훌륭한 블로그 게시물을 작성했습니다:

GUID는 전 세계적으로 고유하지만 GUID의 하위 문자열은 그렇지 않습니다.

해설 (4)

내가 생각하는 이 랜도무이드 사용하기 위한 가장 좋은 예.

http://www.javapractices.com/topic/TopicAction.do? Id = 56

해설 (0)

그냥 임의의 긴 값을 생성하는 것이 더 낫습니다. 그러면 모든 비트가 무작위입니다. Java 6에서 새로운 Random()은 System.nanoTime()과 카운터를 시드로 사용합니다.

고유성에는 여러 수준이 있습니다.

여러 컴퓨터에서 고유성이 필요한 경우 고유 ID를 할당하기 위한 중앙 데이터베이스 테이블을 사용하거나 고유 ID의 배치를 사용할 수도 있습니다.

하나의 앱에만 고유성이 필요한 경우 카운터(또는 요구 사항에 따라 currentTimeMillis()*1000 또는 nanoTime()에서 시작하는 카운터)만 있으면 됩니다.

해설 (0)

'시간' (년 + 일 년) 를 사용하여 야이디드 접두어입니다. 이렇게 하면 조각화가 및 데이터베이스 테이블에서 indexe. 이 방법은 '바이트입니다 되돌려줍니다 [40]'. 내가 그 환경에서 사용할 수 있는 하이브리드 Active Directory SID ('varbinary 입니다 (85)') 는 자동으로 응용 프로그램을 위한 핵심 ladap 사용자와 사용자 ID 비사양 ladap 사용됩니다. 또한 많은 수의 트랜잭션을 사용할 수 없는 '표준' Int 하루 트랜잭션용 테이블 (은행 업계의) 의 키로 유형

private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000");

public static byte[] getSidWithCalendar() {
    Calendar cal = Calendar.getInstance();
    String val = String.valueOf(cal.get(Calendar.YEAR));
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
    val += UUID.randomUUID().toString().replaceAll("-", "");
    return val.getBytes();
}
해설 (1)