/* * (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; /** * ��������Ψһ��ID��16���ֽڣ�128λ��ͬʱ�ṩ��һЩ���߷����� * * @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(); } /** * ��ȡMD5֮���uniqId string * * @return uniqId md5 string */ public String getUniqIDHashString() { return this.hashString(this.getUniqID()); } /** * ��ȡMD5֮���uniqId * * @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(); } } }