001    /*
002     * Copyright (c) 2003, The Regents of the University of California, through
003     * Lawrence Berkeley National Laboratory (subject to receipt of any required
004     * approvals from the U.S. Dept. of Energy). All rights reserved.
005     */
006    package gov.lbl.dsd.sea.nio.util;
007    
008    import java.security.SecureRandom;
009    import java.util.Random;
010    
011    /**
012     * Utilities to create Universally Unique Identifiers as defined by IETF standards.
013     * 
014     * @author whoschek@lbl.gov
015     * @author $Author: hoschek3 $
016     * @version $Revision: 1.2 $, $Date: 2004/07/27 00:18:19 $ 
017     */
018    public class UUIDUtil {
019    
020            private static Random randomGenerator;
021    
022            /**
023             * Make non-instantiable  
024             */
025            protected UUIDUtil() {}
026    
027            /**
028             * Returns a type 4 (pseudo randomly generated) Universally Unique Identifier 
029             * as defined by IETF standards. Example UUID: <code>e96d0caf-76f4-44a9-904e-cad4c0f93b22</code>.
030             * The returned UUID consists of 36 characters. Note that this method is thread-safe.
031             * <p>
032             * See <a href="http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/draft-leach-uuids-guids-01.txt">draft-leach-uuids-guids-01.txt</a> 
033             * for details.
034             * 
035             * @param generator -
036             *            the (pseudo) random number generator used to generate random
037             *            bytes. Set this parameter to <code>null</code> to use a
038             *            built-in default secure random number generator.
039             * 
040             * @return a randomly generated UUID.
041             */
042            public static String createRandomUUID(Random generator) {
043                    if (generator == null) {
044                            if (randomGenerator == null) randomGenerator = new SecureRandom();
045                            generator = randomGenerator;
046                    }
047                    
048                    byte[] data = new byte[16];
049                    generator.nextBytes(data);
050                    data[6] &= 0x0f;
051                    data[6] |= 0x40;
052                    data[8] &= 0x3f;
053                    data[8] |= 0x80;
054                    
055                    String chars = "0123456789abcdefABCDEF";
056                    StringBuffer buf = new StringBuffer(36);
057                    for (int i = 0; i < 16; i++) {
058                            if (i==4 || i==6 || i==8 || i==10) buf.append('-');
059                            int val = data[i] & 0xFF;
060                            buf.append(chars.charAt(val >> 4));
061                            buf.append(chars.charAt(val & 0x0f));
062                    }
063                    return buf.toString();
064            }
065        
066    }