01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one or more
03: * contributor license agreements. See the NOTICE file distributed with
04: * this work for additional information regarding copyright ownership.
05: * The ASF licenses this file to You under the Apache License, Version 2.0
06: * (the "License"); you may not use this file except in compliance with
07: * the License. You may obtain a copy of the License at
08: *
09: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
16: */
17: package org.apache.catalina.tribes.util;
18:
19: import java.security.SecureRandom;
20: import java.util.Random;
21:
22: /**
23: * simple generation of a UUID
24: * @author Filip Hanik
25: * @version 1.0
26: */
27: public class UUIDGenerator {
28: public static final int UUID_LENGTH = 16;
29: public static final int UUID_VERSION = 4;
30: public static final int BYTES_PER_INT = 4;
31: public static final int BITS_PER_BYTE = 8;
32:
33: protected static SecureRandom secrand = null;
34: protected static Random rand = new Random(System
35: .currentTimeMillis());
36: static {
37: secrand = new SecureRandom();
38: secrand.setSeed(rand.nextLong());
39: }
40:
41: public static byte[] randomUUID(boolean secure) {
42: byte[] result = new byte[UUID_LENGTH];
43: return randomUUID(secure, result, 0);
44: }
45:
46: public static byte[] randomUUID(boolean secure, byte[] into,
47: int offset) {
48: if ((offset + UUID_LENGTH) > into.length)
49: throw new ArrayIndexOutOfBoundsException("Unable to fit "
50: + UUID_LENGTH + " bytes into the array. length:"
51: + into.length + " required length:"
52: + (offset + UUID_LENGTH));
53: Random r = (secure && (secrand != null)) ? secrand : rand;
54: nextBytes(into, offset, UUID_LENGTH, r);
55: into[6 + offset] &= 0x0F;
56: into[6 + offset] |= (UUID_VERSION << 4);
57: into[8 + offset] &= 0x3F; //0011 1111
58: into[8 + offset] |= 0x80; //1000 0000
59: return into;
60: }
61:
62: /**
63: * Same as java.util.Random.nextBytes except this one we dont have to allocate a new byte array
64: * @param into byte[]
65: * @param offset int
66: * @param length int
67: * @param r Random
68: */
69: public static void nextBytes(byte[] into, int offset, int length,
70: Random r) {
71: int numRequested = length;
72: int numGot = 0, rnd = 0;
73: while (true) {
74: for (int i = 0; i < BYTES_PER_INT; i++) {
75: if (numGot == numRequested)
76: return;
77: rnd = (i == 0 ? r.nextInt() : rnd >> BITS_PER_BYTE);
78: into[offset + numGot] = (byte) rnd;
79: numGot++;
80: }
81: }
82: }
83:
84: }
|