/**
 * Consider this class public domain - do whatever the hell you
 * like with it - just bear in mind there's no warranty.
 */

import java.net.*;
import java.util.Calendar;

/**
 * Type 1 (time-based) Pure-Java UUID Generator
 *
 * This has the advantage of not using SecureRandom (being
 * time-based) and is therefore fast. Note that it uses the
 * hostname and a some random entropy to construct a node 
 * rather than the ethernet MAC address (to keep it pure java).
 * Despite this limitation, it should still produce very good,
 * unique UUIDs since the mix of hostname/randomness and UTC
 * since the epoch down to the millisecond should be good enough
 * for most applications.
 *
 * The output format is a UUID URN according to the IETF draft, which
 * you can find here:
 *
 * http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-03.txt
 * 
 * @author R. Rawson-Tetley
 * 26th October, 2004
 */
public abstract class UUIDGenerator {

    public static String generateUUID() {

	byte[] data = new byte[16];
		
	Calendar cal = Calendar.getInstance();
	
	data[0] = (byte) cal.get(Calendar.MILLISECOND);
	data[1] = (byte) cal.get(Calendar.SECOND);
	data[2] = (byte) cal.get(Calendar.MINUTE);
	data[3] = (byte) cal.get(Calendar.HOUR_OF_DAY);       // ^ time_low
	data[4] = (byte) cal.get(Calendar.DAY_OF_MONTH);  
	data[5] = (byte) cal.get(Calendar.MONTH);                  // ^ time_mid
	data[6] = (byte) cal.get(Calendar.YEAR);
	data[7] = (byte) (( Math.random() *  8) + 16) ; // ^ time_high and version (0001 in most significant 4 bits for version 1)
	data[8] = (byte) ( Math.random() *  255); // clock_seq
	data[9] = (byte) ( Math.random() *  255); // clock_seq_low
	
	// Get the first 6 bytes of the hostname
	String hostname = "NOHOST";
	try {
		InetAddress addr =  InetAddress.getLocalHost();
		hostname = addr.getHostName();
		// If the hostname is shorter than 6 chars, bulk it out
		if (hostname.length() < 6)
			hostname += "bFrGlP".substring(0, 6 - hostname.length());
	}
	catch (Exception e) {}
	byte[] hostbyte = hostname.getBytes();
	
	data[10] = hostbyte[0];
	data[11] = hostbyte[1];
	data[12] = hostbyte[2];
	data[13] = hostbyte[3];
	data[14] = hostbyte[4];
	data[15] = hostbyte[5]; 
	
	String chars = "0123456789abcdefABCDEF";
	StringBuffer buf = new StringBuffer(36);
	for (int i = 0; i < 16; i++) {
		if (i==4 || i==6 || i==8 || i==10) buf.append('-');
		int val = data[i] & 0xFF;
		buf.append(chars.charAt(val >> 4));
		buf.append(chars.charAt(val & 0x0f));
	}
	return "uuid:" + buf.toString();

    }
	
}
