FileDocCategorySizeDatePackage
FastUUIDGen.javaAPI DocApache Axis 1.44781Sat Apr 22 18:57:28 BST 2006org.apache.axis.components.uuid

FastUUIDGen

public class FastUUIDGen extends Object implements UUIDGen
Creates time-based UUID's. See the UUID Internet Draft for details.
author
Jarek Gawor (gawor@apache.org)

Fields Summary
private static Random
secureRandom
private static String
nodeStr
private static int
clockSequence
private long
lastTime
Constructors Summary
Methods Summary
private static longgetBitsValue(long value, int startBit, int bitLen)

        return ((value << (64-startBit)) >>> (64-bitLen));
    
private static intgetClockSequence()

        return secureRandom.nextInt(16384);
    
private static java.lang.StringgetNodeHexValue()


     
        // problem: the node should be the IEEE 802 ethernet address, but can not
        // be retrieved in Java yet.
        // see bug ID 4173528
        // workaround (also suggested in bug ID 4173528)
        // If a system wants to generate UUIDs but has no IEE 802 compliant
        // network card or other source of IEEE 802 addresses, then this section
        // describes how to generate one.
        // The ideal solution is to obtain a 47 bit cryptographic quality random
        // number, and use it as the low 47 bits of the node ID, with the most
        // significant bit of the first octet of the node ID set to 1. This bit
        // is the unicast/multicast bit, which will never be set in IEEE 802
        // addresses obtained from network cards; hence, there can never be a
        // conflict between UUIDs generated by machines with and without network
        // cards.
        try {
            secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN");
        } catch (Exception e) {
            secureRandom = new Random();
        }

        nodeStr = getNodeHexValue();
        clockSequence = getClockSequence();
    
        long node = 0;
        long nodeValue = 0;
        while ( (node = getBitsValue(nodeValue, 47, 47)) == 0 ) {
            nodeValue = secureRandom.nextLong();
        }
        node = node | 0x800000000000L;
        return leftZeroPadString(Long.toHexString(node), 12);
    
private static final java.lang.StringleftZeroPadString(java.lang.String bitString, int len)

        if (bitString.length() < len) {
            int nbExtraZeros = len - bitString.length();
            StringBuffer extraZeros = new StringBuffer();
            for (int i = 0; i < nbExtraZeros; i++) {
                extraZeros.append("0");
            }
            extraZeros.append(bitString);
            bitString = extraZeros.toString();
        }
        return bitString;
    
public java.lang.StringnextUUID()

        long time = System.currentTimeMillis();

        long timestamp = time * 10000;
        timestamp += 0x01b21dd2L << 32;
        timestamp += 0x13814000;
        
        synchronized(this) {
            if (time - lastTime <= 0) {
                clockSequence = ((clockSequence + 1) & 16383);
            }
            lastTime = time;
        }

        long timeLow = getBitsValue(timestamp, 32, 32);
        long timeMid = getBitsValue(timestamp, 48, 16);
        long timeHi = getBitsValue(timestamp, 64, 16) | 0x1000;

        long clockSeqLow = getBitsValue(clockSequence, 8, 8);
        long clockSeqHi = getBitsValue(clockSequence, 16, 8) | 0x80;
        
        String timeLowStr = leftZeroPadString(Long.toHexString(timeLow), 8);
        String timeMidStr = leftZeroPadString(Long.toHexString(timeMid), 4);
        String timeHiStr = leftZeroPadString(Long.toHexString(timeHi), 4);

        String clockSeqHiStr = leftZeroPadString(Long.toHexString(clockSeqHi), 2);
        String clockSeqLowStr = leftZeroPadString(Long.toHexString(clockSeqLow), 2);

        StringBuffer result = new StringBuffer(36);
        result.append(timeLowStr).append("-");
        result.append(timeMidStr).append("-");
        result.append(timeHiStr).append("-");
        result.append(clockSeqHiStr).append(clockSeqLowStr);
        result.append("-").append(nodeStr);

        return result.toString();