001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.toolkit;
025:
026: import java.security.SecureRandom;
027:
028: //import java.util.Random;
029:
030: /**
031: * <p>
032: * Name: UUIDGen.java
033: * </p>
034: *
035: * <p>
036: * Author: uk-dave (http://www.uk-dave.com)
037: * </p>
038: *
039: * <p>
040: * Date: 23th July 2003
041: * </p>
042: *
043: * <p>
044: * Description: Generates random-number based UUIDs This program should really use
045: * java.security.SecureRandom to ensure that random numbers are truly random (well, as near as),
046: * but because this program is to be used on TINI's and SNAP's plain old java.util.Random has to
047: * be used instead.
048: * </p>
049: *
050: * <p>
051: * Useful Links:<br>
052: * <a href="http://www.dsps.net/uuid.html">What is a UUID?</a><br>
053: * <a href="http://www.opengroup.org/onlinepubs/9629399/apdxa.htm">UUID Spec</a><br>
054: * <a href="http://www.doomdark.org/doomdark/proj/jug/">Proper Java UUID Generator</a><br>
055: * </p>
056: */
057: public final class UUIDGen {
058: private static final String hexChars = "0123456789abcdef";
059: private static final byte INDEX_TYPE = 6;
060: private static final byte INDEX_VARIATION = 8;
061: private static final byte TYPE_RANDOM_BASED = 4;
062: private static UUIDGen INSTANCE = new UUIDGen();
063: private SecureRandom rnd;
064:
065: /**
066: * Constructor. Instantiates the rnd object to generate random numbers.
067: */
068: private UUIDGen() {
069: rnd = new SecureRandom();
070: }
071:
072: /**
073: * Returns the UUIDGen instance
074: *
075: * @return {@link UUIDGen}
076: */
077: public static UUIDGen getInstance() {
078: if (UUIDGen.INSTANCE == null) {
079: UUIDGen.INSTANCE = new UUIDGen();
080: }
081:
082: return UUIDGen.INSTANCE;
083: }
084:
085: /**
086: * Generates a random UUID and returns the String representation of it.
087: *
088: * @return a String representing a randomly generated UUID.
089: */
090: public String generateUUID() {
091: // Generate 128-bit random number
092: byte[] uuid = new byte[16];
093: nextRandomBytes(uuid);
094:
095: // Set various bits such as type
096: uuid[INDEX_TYPE] &= (byte) 0x0F;
097: uuid[INDEX_TYPE] |= (byte) (TYPE_RANDOM_BASED << 4);
098: uuid[INDEX_VARIATION] &= (byte) 0x3F;
099: uuid[INDEX_VARIATION] |= (byte) 0x80;
100:
101: // Convert byte array into a UUID formatted string
102: StringBuffer b = new StringBuffer(36);
103:
104: for (int i = 0; i < 16; i++) {
105: if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) {
106: b.append('-');
107: }
108:
109: int hex = uuid[i] & 0xFF;
110: b.append(hexChars.charAt(hex >> 4));
111: b.append(hexChars.charAt(hex & 0x0F));
112: }
113:
114: // Return UUID
115: return b.toString();
116: }
117:
118: /**
119: * <p>
120: * Generates random bytes and places them into a user-supplied byte array. The number of random
121: * bytes produced is equal to the length of the byte array. Nicked from java.util.Random
122: * because the stupid SNAP board doesn't have this method!
123: * </p>
124: *
125: * @param bytes the non-null byte array in which to put the random bytes.
126: */
127: private void nextRandomBytes(byte[] bytes) {
128: int numRequested = bytes.length;
129: int numGot = 0;
130: int rand = 0;
131:
132: while (true) {
133: for (int i = 0; i < 4; i++) {
134: if (numGot == numRequested) {
135: return;
136: }
137:
138: rand = ((i == 0) ? rnd.nextInt() : (rand >> 8));
139: bytes[numGot++] = (byte) rand;
140: }
141: }
142: }
143: }
|