com.taobao.common.store.util.UniqId.java Source code

Java tutorial

Introduction

Here is the source code for com.taobao.common.store.util.UniqId.java

Source

/*
 * (C) 2007-2012 Alibaba Group Holding Limited.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * Authors:
 *   huangshang (yuexuqiang at gmail.com)
 */
package com.taobao.common.store.util;

import java.io.IOException;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;

/**
 * ID16128
 * 
 * @author huangshang (yuexuqiang at gmail.com)
 * 
 */
public class UniqId {
    private final Log log = LogFactory.getLog(UniqId.class);
    private static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
            'f' };
    private static UniqId me = new UniqId();
    private String hostAddr;
    private final Random random = new SecureRandom();
    private MessageDigest mHasher;
    private final UniqTimer timer = new UniqTimer();

    private final ReentrantLock opLock = new ReentrantLock();

    private UniqId() {
        try {
            final InetAddress addr = InetAddress.getLocalHost();

            hostAddr = addr.getHostAddress();
        } catch (final IOException e) {
            log.error("[UniqID] Get HostAddr Error", e);
            hostAddr = String.valueOf(System.currentTimeMillis());
        }

        if (null == hostAddr || hostAddr.trim().length() == 0 || "127.0.0.1".equals(hostAddr)) {
            hostAddr = String.valueOf(System.currentTimeMillis());
        }

        if (log.isDebugEnabled()) {
            log.debug("[UniqID]hostAddr is:" + hostAddr);
        }

        try {
            mHasher = MessageDigest.getInstance("MD5");
        } catch (final NoSuchAlgorithmException nex) {
            mHasher = null;
            log.error("[UniqID]new MD5 Hasher error", nex);
        }
    }

    /**
     * UniqID
     * 
     * @return UniqId
     */
    public static UniqId getInstance() {
        return me;
    }

    /**
     * 
     * 
     * @return 
     */
    public long getUniqTime() {
        return timer.getCurrentTime();
    }

    /**
     * UniqId
     * 
     * @return uniqTime-randomNum-hostAddr-threadId
     */
    public String getUniqID() {
        final StringBuffer sb = new StringBuffer();
        final long t = timer.getCurrentTime();

        sb.append(t);

        sb.append("-");

        sb.append(random.nextInt(8999) + 1000);

        sb.append("-");
        sb.append(hostAddr);

        sb.append("-");
        sb.append(Thread.currentThread().hashCode());

        if (log.isDebugEnabled()) {
            log.debug("[UniqID.getUniqID]" + sb.toString());
        }

        return sb.toString();
    }

    /**
     * MD5uniqId string
     * 
     * @return uniqId md5 string
     */
    public String getUniqIDHashString() {
        return this.hashString(this.getUniqID());
    }

    /**
     * MD5uniqId
     * 
     * @return uniqId md5 byte[16]
     */
    public byte[] getUniqIDHash() {
        return this.hash(this.getUniqID());
    }

    /**
     * md5
     * 
     * @param str
     * @return md5 byte[16]
     */
    public byte[] hash(final String str) {
        opLock.lock();
        try {
            final byte[] bt = mHasher.digest(str.getBytes());
            if (null == bt || bt.length != 16) {
                throw new IllegalArgumentException("md5 need");
            }
            return bt;
        } finally {
            opLock.unlock();
        }
    }

    /**
     * md5 string
     * 
     * @param str
     * @return md5 string
     */
    public String hashString(final String str) {
        final byte[] bt = this.hash(str);
        return this.bytes2string(bt);
    }

    /**
     * 
     * 
     * @param bt
     * @return f1d2
     */
    public String bytes2string(final byte[] bt) {
        final int l = bt.length;

        final char[] out = new char[l << 1];

        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = digits[(0xF0 & bt[i]) >>> 4];
            out[j++] = digits[0x0F & bt[i]];
        }

        if (log.isDebugEnabled()) {
            log.debug("[UniqID.hash]" + (new String(out)));
        }

        return new String(out);
    }

    /**
     * 
     * 
     * @author dogun
     */
    private class UniqTimer {
        private final AtomicLong lastTime = new AtomicLong(System.currentTimeMillis());

        public long getCurrentTime() {
            return this.lastTime.incrementAndGet();
        }
    }
}