web-dev-qa-db-ja.com

UUID.randomUUID()とSecureRandom

SecureRandomジェネレーターが内部でsecurerandomを使用しているため、SecureRandomジェネレーターよりもUUID.randomUUID()を使用する利点を理解しようとしています。

16
User3518958

ソースコードUUID.randomUUIDSecureRandom を使用します。

public static UUID  [More ...] randomUUID() {
    SecureRandom ng = numberGenerator;
    if (ng == null) {
        numberGenerator = ng = new SecureRandom();
    }
    byte[] randomBytes = new byte[16];
    ng.nextBytes(randomBytes);
    randomBytes[6]  &= 0x0f;  /* clear version        */
    randomBytes[6]  |= 0x40;  /* set to version 4     */
    randomBytes[8]  &= 0x3f;  /* clear variant        */
    randomBytes[8]  |= 0x80;  /* set to IETF variant  */
    return new UUID(randomBytes);
}

ご覧のとおり、どちらでも使用できますが、安全なUUIDには6つのランダムでないビットがあります。

24
uoyilmaz

乱数はランダムに繰り返される可能性があります。ランダム性が低いほど(ある程度の調整がない限り)、同じ数値が2回生成される可能性が高くなります。

https://en.wikipedia.org/wiki/Birthday_problem
より多くの乱数を生成すると、すべてのIDが他のすべてのIDと異なる必要があるため、同じ番号が繰り返される可能性が高くなります。

SecureRandomを使用すると、ランダム性のビット数を選択できます。小さすぎると繰り返される可能性が高くなります。重複したランダムな32ビットIDをほんの一瞬で取得できます。

UUIDは標準を128ビットに設定します(またはuoyilmazが指摘するように、122ビットはランダムです)これはほとんどのユースケースで十分です。ただし、ランダムな文字列が必要な場合は、16よりも多くのビットおよび/またはより高いベースを使用したいと思います。たとえば、Javaは、ベース36および64をサポートします。つまり、IDを短くしたり、同じ長さのID。

注:UUID形式のダンプには複数の-が含まれていますが、それらの値は表示されません。文字列が長くなるだけです。

6
Peter Lawrey