生成唯一ID

因为业务需求所以需要一个ID生成器,要求生成器16位ID唯一。UUID太长不适合需求,所以琢磨了一个。总体思路就是,借助UUID(毕竟人家全球唯一,自己写太麻烦了)生成一个baseID,然后搞个位权出来进行数据整合算出所需要的ID。后来经过领导的开导又把生成器变为动态生成,其实就是可生成14到32位任意ID。下面直接上代码了。

package com.ecej.admin.common.utils;

import java.io.Serializable;
import java.util.UUID;

/**
 * 
 * 
 * @author QIANG
 */
public abstract class UniCodeUtil implements Serializable {

	private static final long serialVersionUID = -5628028113003022356L;

	private static final int MAX_SIZE = 25;
	private static final int MIN_SIZE = 14;
	private static final int BASE_SIZE = 2;

	/**
	 * 默认生成RCID 12位
	 * 
	 * @return
	 */
	public static String rand() {
		return rand(16);
	}

	/**
	 * 根据传入值生成相应位数随机码
	 * 
	 * @param offset 最大生成40位,最小生成14位 (位权基础系数为4) 4 6 8 1 2 3
	 * 
	 * @return
	 */
	public static String rand(int offset) {

		if (offset > MAX_SIZE || offset < MIN_SIZE) {
			return "";
		}
		int div = offset / 10;
		int bitSize = BASE_SIZE + (div << 2 >> 1);
		int baseSize = offset - bitSize;

		String baseID = randomBaseID(baseSize);

		StringBuilder rcid = new StringBuilder(baseID);
		String rv = bitWeight(bitSize);
		char[] ch = rv.toCharArray();
		for (char c : ch) {
			rcid.insert(Character.getNumericValue(c), c);
		}
		return rcid.toString().toUpperCase();
	}

	/**
	 * 根据UUID生成随机指定位数位ID
	 * 
	 * @return
	 */
	public static String randomBaseID(int baseSize) {
		UUID uid = UUID.randomUUID();
		long idx = uid.getLeastSignificantBits();
		StringBuilder buff = new StringBuilder();
		for (int i = 0; i < 12; i++) {
			buff.append(toa(0x1F & idx));
			idx >>>= 5;
		}
		long idxb = uid.getMostSignificantBits();
		buff.append(toa((idxb & 0x1) == 0 ? idx : idx + 0x10));
		idx = (idxb >>> 1);
		for (int i = 0; i < 13; i++) {
			buff.append(toa(0x1F & idx));
			idx >>>= 5;
		}
		return buff.reverse().toString().substring(0, baseSize);
	}

	/**
	 * 获取位权数
	 * 
	 * @return
	 */
	private static String bitWeight(int bitSize) {
		String str = String.valueOf(Math.random()).substring(2);
		while (str.length() < bitSize || str.indexOf('-') > 0) {
			str = String.valueOf(Math.random()).substring(2);
		}
		return str.substring(0, bitSize);
	}

	/**
	 * 生成可见字符
	 * 
	 * @param lidx
	 * @return
	 */
	private static char toa(long lidx) {
		if (lidx < 10) {
			return (char) (0x30 + lidx);
		}
		lidx += (0x41 - 10);
		int[] skips = { 0x49, 0x4f, 0x57, 0x5a };
		for (int ch : skips) {
			if (lidx < ch) {
				break;
			}
			lidx++;
		}
		return (char) lidx;
	}
}



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

架构技术专栏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值