/** * Copyright 2013-2014 the original author or authors. * * 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. */ package com.iflytek.edu.cloud.frame.utils; import java.net.NetworkInterface; import java.nio.ByteBuffer; import java.util.Enumeration; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 详细描述请参考:http://www.cnblogs.com/xjk15082/archive/2011/09/18/2180792.html * * @author libinsong1204@gmail.com * @date 2012-3-2 上午10:05:38 */ public class MongodbUniqueIdGenerator { static final Logger LOGGER = LoggerFactory.getLogger(MongodbUniqueIdGenerator.class); private static AtomicInteger _nextInc = new AtomicInteger( (new java.util.Random()).nextInt()); private MongodbUniqueIdGenerator() { } public static String getUniqueId() { int _time = (int) (System.currentTimeMillis() / 1000); int _machine = _genmachine; int _inc = _nextInc.getAndIncrement(); byte b[] = new byte[12]; ByteBuffer bb = ByteBuffer.wrap(b); // by default BB is big endian like we need bb.putInt(_time); bb.putInt(_machine); bb.putInt(_inc); StringBuilder buf = new StringBuilder(24); for (int i = 0; i < b.length; i++) { int x = b[i] & 0xFF; String s = Integer.toHexString(x); if (s.length() == 1) buf.append("0"); buf.append(s); } return buf.toString(); } private static final int _genmachine; static { try { // build a 2-byte machine piece based on NICs info final int machinePiece; { StringBuilder sb = new StringBuilder(); Enumeration<NetworkInterface> e = NetworkInterface .getNetworkInterfaces(); while (e.hasMoreElements()) { NetworkInterface ni = e.nextElement(); sb.append(ni.toString()); } machinePiece = sb.toString().hashCode() << 16; LOGGER.info("machine piece post: " + Integer.toHexString(machinePiece)); } // add a 2 byte process piece. It must represent not only the JVM // but the class loader. // Since static var belong to class loader there could be collisions // otherwise final int processPiece; { int processId = new java.util.Random().nextInt(); try { processId = java.lang.management.ManagementFactory .getRuntimeMXBean().getName().hashCode(); } catch (Throwable t) { //emtry } ClassLoader loader = MongodbUniqueIdGenerator.class.getClassLoader(); int loaderId = loader != null ? System.identityHashCode(loader) : 0; StringBuilder sb = new StringBuilder(); sb.append(Integer.toHexString(processId)); sb.append(Integer.toHexString(loaderId)); processPiece = sb.toString().hashCode() & 0xFFFF; LOGGER.info("process piece: " + Integer.toHexString(processPiece)); } _genmachine = machinePiece | processPiece; LOGGER.info("machine : " + Integer.toHexString(_genmachine)); } catch (java.io.IOException ioe) { throw new RuntimeException(ioe); } } public static void main(String[] args) { System.out.println(MongodbUniqueIdGenerator.getUniqueId()); System.out.println(MongodbUniqueIdGenerator.getUniqueId()); System.out.println(MongodbUniqueIdGenerator.getUniqueId()); } }