content: package com.ctrip.framework.apollo.common.utils;
  
  import com.google.common.base.Joiner;
  
  import com.ctrip.framework.apollo.core.utils.ByteUtil;
  import com.ctrip.framework.apollo.core.utils.MachineUtil;
  
  import org.apache.commons.lang.time.FastDateFormat;
  
  import java.security.SecureRandom;
  import java.util.Date;
  import java.util.Objects;
  import java.util.concurrent.atomic.AtomicInteger;
  
  public class UniqueKeyGenerator {
  
    private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmss");
    private static final AtomicInteger counter = new AtomicInteger(new SecureRandom().nextInt());
    private static final Joiner KEY_JOINER = Joiner.on("-");
  
  
  
    public static String generate(Object... args){
      String hexIdString =
          ByteUtil.toHexString(toByteArray(Objects.hash(args), MachineUtil.getMachineIdentifier(),
                                           counter.incrementAndGet()));
  
      return KEY_JOINER.join(TIMESTAMP_FORMAT.format(new Date()), hexIdString);
  
    }
  
    /**
     * Concat machine id, counter and key to byte array
     * Only retrieve lower 3 bytes of the id and counter and 2 bytes of the keyHashCode
     */
    protected static byte[] toByteArray(int keyHashCode, int machineIdentifier, int counter) {
      byte[] bytes = new byte[8];
      bytes[0] = ByteUtil.int1(keyHashCode);
      bytes[1] = ByteUtil.int0(keyHashCode);
      bytes[2] = ByteUtil.int2(machineIdentifier);
      bytes[3] = ByteUtil.int1(machineIdentifier);
      bytes[4] = ByteUtil.int0(machineIdentifier);
      bytes[5] = ByteUtil.int2(counter);
      bytes[6] = ByteUtil.int1(counter);
      bytes[7] = ByteUtil.int0(counter);
      return bytes;
    }
  
  
  }
  