REST APIのセッショントークンを作成しようとしています。ユーザーがログインするたびに、次の方法で新しいトークンを作成しています。
UUID token = UUID.randomUUID();
user.setSessionId(token.toString());
Sessions.INSTANCE.sessions.put(user.getName(), user.getSessionId());
ただし、sessionTokenの重複を防ぐ方法はわかりません。
例:user1がサインインしてトークン87955dc9-d2ca-4f79-b7c8-b0223a32532a
を取得し、user2がサインインしてalsoがトークン87955dc9-d2ca-4f79-b7c8-b0223a32532a
を取得するというシナリオはありますか。
これを行うより良い方法はありますか?
UUIDの衝突が発生した場合は、次に抽選に参加してください。
ウィキペディアから:
ランダムに生成されたUUIDには、122個のランダムビットがあります。合計128ビットのうち、バージョン(「ランダムに生成されたUUID」)には4ビットが使用され、バリアント(「Leach-Salz」)には2ビットが使用されます。
ランダムなUUIDを使用すると、確率論(誕生日パラドックス)を使用して、2つの値が同じになる確率を計算できます。近似を使用する
p(n)\approx 1-e^{-\tfrac{n^2}{{2x}}}
これらは、x = 2122でn個のUUIDを計算した後の偶発的な衝突の確率です。
n確率68,719,476,736 = 236 0.0000000000000004(4×10-16)2,199,023,255,552 = 241 0.0000000000004(4×10-13)70,368,744,177,664 = 246 0.0000000004(4×10-10)
これらの数値を考慮に入れると、隕石に当たる誰かの年間リスクは170億分の1の確率であると推定されます。これは、確率が約0.00000000006(6×10−11)であることを意味します。 1年で数十兆を超えるUUIDがあり、1つが重複しています。つまり、次の100年間、毎秒10億個のUUIDを生成した後にのみ、複製が1つだけ作成される確率は約50%になります。地球上のすべての人が6億のUUIDを所有している場合、1つの重複の確率は約50%になります。
UUIDのサイズは有限であるため、すべての空間と時間にわたって一意である方法はありません。
妥当なユースケース内で一意であることが保証されているUUIDが必要な場合は、Log4j 2のUuid.getTimeBasedUuid()を使用できます。 1ミリ秒あたり10,000未満のUUIDを生成する限り、約8,900年間は一意であることが保証されています。
Oracle UUIDドキュメント。 http://docs.Oracle.com/javase/7/docs/api/Java/util/UUID.html
彼らは、Internet Engineering Task Forceのこのアルゴリズムを使用しています。 http://www.ietf.org/rfc/rfc4122.txt
要約からの引用。
UUIDは128ビット長であり、空間と時間にわたって一意性を保証できます。
アブストラクトは保証を主張していますが、3.4 x 10^38
の組み合わせ。 CodeChimp