001/* 002 * Copyright 2002-2015 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.util; 018 019import java.math.BigInteger; 020import java.security.SecureRandom; 021import java.util.Random; 022import java.util.UUID; 023 024/** 025 * An {@link IdGenerator} that uses {@link SecureRandom} for the initial seed and 026 * {@link Random} thereafter, instead of calling {@link UUID#randomUUID()} every 027 * time as {@link org.springframework.util.JdkIdGenerator JdkIdGenerator} does. 028 * This provides a better balance between securely random ids and performance. 029 * 030 * @author Rossen Stoyanchev 031 * @author Rob Winch 032 * @since 4.0 033 */ 034public class AlternativeJdkIdGenerator implements IdGenerator { 035 036 private final Random random; 037 038 039 public AlternativeJdkIdGenerator() { 040 SecureRandom secureRandom = new SecureRandom(); 041 byte[] seed = new byte[8]; 042 secureRandom.nextBytes(seed); 043 this.random = new Random(new BigInteger(seed).longValue()); 044 } 045 046 047 @Override 048 public UUID generateId() { 049 byte[] randomBytes = new byte[16]; 050 this.random.nextBytes(randomBytes); 051 052 long mostSigBits = 0; 053 for (int i = 0; i < 8; i++) { 054 mostSigBits = (mostSigBits << 8) | (randomBytes[i] & 0xff); 055 } 056 057 long leastSigBits = 0; 058 for (int i = 8; i < 16; i++) { 059 leastSigBits = (leastSigBits << 8) | (randomBytes[i] & 0xff); 060 } 061 062 return new UUID(mostSigBits, leastSigBits); 063 } 064 065}