diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/id/ObjectId.java b/hutool-core/src/main/java/cn/hutool/core/lang/id/ObjectId.java index 67dc11949..f8f260910 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/id/ObjectId.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/id/ObjectId.java @@ -1,14 +1,9 @@ package cn.hutool.core.lang.id; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.classloader.ClassLoaderUtil; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.core.util.RuntimeUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.RandomUtil; -import java.net.NetworkInterface; -import java.nio.ByteBuffer; -import java.util.Enumeration; +import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; /** @@ -18,37 +13,41 @@ import java.util.concurrent.atomic.AtomicInteger; *
* 1. Time 时间戳。 * 2. Machine 所在主机的唯一标识符,一般是机器主机名的散列值。 - * 3. PID 进程ID。确保同一机器中不冲突 + * 3. 随机数 * 4. INC 自增计数器。确保同一秒内产生objectId的唯一性。 ** *
时间戳 | - *机器ID | - *进程ID | + *随机数 | *自增计数器 | *|
4 | - *3 | - *2 | - *3 | + *4 | + *4 | *
+ * 参考:...
*
* @author looly
* @since 4.0.0
- *
*/
public class ObjectId {
-
- /** 线程安全的下一个随机数,每次生成自增+1 */
+ /**
+ * 16进制字符
+ */
+ private static final char[] HEX_UNIT = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ /**
+ * 线程安全的下一个随机数,每次生成自增+1
+ */
private static final AtomicInteger NEXT_INC = new AtomicInteger(RandomUtil.randomInt());
- /** 机器信息 */
- private static final int MACHINE = getMachinePiece() | getProcessPiece();
+ /**
+ * 机器信息
+ */
+ private static final char[] MACHINE_CODE = initMachineCode();
/**
* 给定的字符串是否为有效的ObjectId
@@ -90,21 +89,31 @@ public class ObjectId {
* @since 4.1.15
*/
public static byte[] nextBytes() {
- final ByteBuffer bb = ByteBuffer.wrap(new byte[12]);
- bb.putInt((int) DateUtil.currentSeconds());// 4位
- bb.putInt(MACHINE);// 4位
- bb.putInt(NEXT_INC.getAndIncrement());// 4位
-
- return bb.array();
+ return next().getBytes();
}
/**
- * 获取一个objectId用下划线分割
+ * 获取一个objectId【没有下划线】。
*
* @return objectId
*/
public static String next() {
- return next(false);
+ final char[] ids = new char[24];
+ int epoch = (int) ((System.currentTimeMillis() / 1000));
+ // 4位字节 : 时间戳
+ for (int i = 7; i >= 0; i--) {
+ ids[i] = HEX_UNIT[(epoch & 15)];
+ epoch >>>= 4;
+ }
+ // 4位字节 : 随机数
+ System.arraycopy(MACHINE_CODE, 0, ids, 8, 8);
+ // 4位字节: 自增序列。溢出后,相当于从0开始算。
+ int seq = NEXT_INC.incrementAndGet();
+ for (int i = 23; i >= 16; i--) {
+ ids[i] = HEX_UNIT[(seq & 15)];
+ seq >>>= 4;
+ }
+ return new String(ids);
}
/**
@@ -114,78 +123,41 @@ public class ObjectId {
* @return objectId
*/
public static String next(final boolean withHyphen) {
- final byte[] array = nextBytes();
- final StringBuilder buf = new StringBuilder(withHyphen ? 26 : 24);
- int t;
- for (int i = 0; i < array.length; i++) {
- if (withHyphen && i % 4 == 0 && i != 0) {
- buf.append("-");
- }
- t = array[i] & 0xff;
- if (t < 16) {
- buf.append('0');
- }
- buf.append(Integer.toHexString(t));
-
+ if (false == withHyphen) {
+ return next();
}
- return buf.toString();
- }
-
- // ----------------------------------------------------------------------------------------- Private method start
- /**
- * 获取机器码片段
- *
- * @return 机器码片段
- */
- private static int getMachinePiece() {
- // 机器码
- int machinePiece;
- try {
- final StringBuilder netSb = new StringBuilder();
- // 返回机器所有的网络接口
- final Enumeration