一.UUID的介紹:UUID又稱為通用唯一標(biāo)識符,是一個(gè)128位長的數(shù)字,一般用16進(jìn)制表示,算法的核心思想是結(jié)合機(jī)器的網(wǎng)卡、當(dāng)前時(shí)間和一個(gè)隨機(jī)數(shù)來生成UUID.
二:UUID的形式是:4-2-2-2-6,共4+2+2+2+6=16個(gè)字節(jié)。比如,550e8400-e29b-41d4-a716-446655440000 。其中,第3部分的第一個(gè)字節(jié)(即總體上的第7個(gè)字節(jié))的高4位用來表示uuid的version類型。version表明了uuid的算法版本,目前有如下幾種:
1,version1:version1是第一次提出來的算法,算法使用了唯一硬件地址(比如,網(wǎng)卡啊,cpu編號啊)+精確到100納秒的時(shí)間,還有其他的一些數(shù)據(jù)來產(chǎn)生結(jié)果。可是,它被廣泛的抵制了,因?yàn)楦鶕?jù)uuid可以很容易的查到是那臺電腦構(gòu)建的(因?yàn)榫W(wǎng)卡地址唯一)。傳聞?wù)f有一次網(wǎng)絡(luò)攻擊行為就是被這種方式給追蹤到黑客的。
2,version3:第3版本的算法(很奇怪的是居然沒有第2版本的算法),這個(gè)算法十分簡單,就是使用md5算法hash一個(gè)唯一url地址。保證uuid的唯一需要你自己保證url地址的唯一。
3,version4:第4版本的算法,這個(gè)算法也很容易理解,它是直接使用一個(gè)隨機(jī)數(shù)來構(gòu)建uuid。隨機(jī)數(shù)如何構(gòu)建由自己決定。
4,version5:第5版本的算法,這個(gè)算法和第3版本的算法幾乎一樣,唯一不同的是它使用了sha-1算法代替md5算法來進(jìn)行hash。
三:UUID在使用一
/**
     * 
     * 
@author wangdei
     * 在 
http://www.bt285.cn BT下載
     * 
http://www.5a520.cn 小說520 上使用. 
     *
     
*/

    
public class RandomGUID extends Object {
        
protected final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
           .getLog(getClass());

        
public String valueBeforeMD5 = "";
        
public String valueAfterMD5 = "";
        
private static Random myRand;
        
private static SecureRandom mySecureRand;

        
private static String s_id;
        
private static final int PAD_BELOW = 0x10;
        
private static final int TWO_BYTES = 0xFF;

        
/*
         * Static block to take care of one time secureRandom seed.
         * It takes a few seconds to initialize SecureRandom.   You might
         * want to consider removing this static block or replacing
         * it with a "time since first loaded" seed to reduce this time.
         * This block will run only once per JVM instance.
           
*/


        
static {
           mySecureRand 
= new SecureRandom();
           
long secureInitializer = mySecureRand.nextLong();
           myRand 
= new Random(secureInitializer);
           
try {
              s_id 
= InetAddress.getLocalHost().toString();
           }
 catch (UnknownHostException e) {
              e.printStackTrace();
           }


        }



        
/*
         * Default constructor.   With no specification of security option,
         * this constructor defaults to lower security, high performance.
         
*/

        
public RandomGUID() {
           getRandomGUID(
false);
        }


        
/*
         * Constructor with security option.   Setting secure true
         * enables each random number generated to be cryptographically
         * strong.   Secure false defaults to the standard Random function seeded
         * with a single cryptographically strong random number.
         
*/

        
public RandomGUID(boolean secure) {
           getRandomGUID(secure);
        }


        
/*
         * Method to generate the random GUID
         
*/

        
private void getRandomGUID(boolean secure) {
           MessageDigest md5 
= null;
           StringBuffer sbValueBeforeMD5 
= new StringBuffer(128);

           
try {
              md5 
= MessageDigest.getInstance("MD5");
           }
 catch (NoSuchAlgorithmException e) {
              logger.error(
"Error: " + e);
           }


           
try {
              
long time = System.currentTimeMillis();
              
long rand = 0;

              
if (secure) {
                 rand 
= mySecureRand.nextLong();
              }
 else {
                 rand 
= myRand.nextLong();
              }

              sbValueBeforeMD5.append(s_id);
              sbValueBeforeMD5.append(
":");
              sbValueBeforeMD5.append(Long.toString(time));
              sbValueBeforeMD5.append(
":");
              sbValueBeforeMD5.append(Long.toString(rand));

              valueBeforeMD5 
= sbValueBeforeMD5.toString();
              md5.update(valueBeforeMD5.getBytes());

              
byte[] array = md5.digest();
              StringBuffer sb 
= new StringBuffer(32);
              
for (int j = 0; j < array.length; ++j) {
                 
int b = array[j] & TWO_BYTES;
                 
if (b < PAD_BELOW)
                    sb.append(
'0');
                 sb.append(Integer.toHexString(b));
              }


              valueAfterMD5 
= sb.toString();

           }
 catch (Exception e) {
              logger.error(
"Error:" + e);
           }

        }


        
/*
         * Convert to the standard format for GUID
         * (Useful for SQL Server UniqueIdentifiers, etc.)
         * Example: C2FEEEAC-CFCD-11D1-8B05-00600806D9B6
         
*/

        
public String toString() {
           String raw 
= valueAfterMD5.toUpperCase();
           StringBuffer sb 
= new StringBuffer(64);
           sb.append(raw.substring(
08));
           sb.append(
"-");
           sb.append(raw.substring(
812));
           sb.append(
"-");
           sb.append(raw.substring(
1216));
           sb.append(
"-");
           sb.append(raw.substring(
1620));
           sb.append(
"-");
           sb.append(raw.substring(
20));

           
return sb.toString();
        }



          
// Demonstraton and self test of class
          public static void main(String args[]) {
            
for (int i=0; i< 100; i++{
              RandomGUID myGUID 
= new RandomGUID();
              System.out.println(
"Seeding String=" + myGUID.valueBeforeMD5);
              System.out.println(
"rawGUID=" + myGUID.valueAfterMD5);
              System.out.println(
"RandomGUID=" + myGUID.toString());
            }

          }



    }

四:UUID在使用二
可以采用一個(gè)開源實(shí)現(xiàn):http://jug.safehaus.org/ 或者用jakarta commons下的http://jakarta.apache.org/commons/sandbox/id/
五:UUID在使用三
Java1.5中,已經(jīng)包含了一個(gè)UUID的實(shí)現(xiàn)java.util.UUID。要隨機(jī)生成一個(gè)UUID,只要用兩行代碼就可以了:String uuid = UUID.randomUUID().toString(); 目前UUID類只提供了根據(jù)md5和根據(jù)隨機(jī)數(shù)來構(gòu)建uuid的算法(即第3和第4個(gè)版本的算法)。