简介
生成随机数,一般来说用的不是很多,会用一些第三方的工具包来生成分布式ID
源码
public final class UUID implements java.io.Serializable, Comparable<UUID> {private static final long serialVersionUID = -4856846361193249489L;// uuid 的最高有效位为64位private final long mostSigBits;// uuid 的最低有效位为64位private final long leastSigBits;// 此类使用的随机数生成器来创建基于随机的UUID。private static class Holder {static final SecureRandom numberGenerator = new SecureRandom();}// 私有构造函数,它使用字节数组构造新的UUID。private UUID(byte[] data) {long msb = 0;long lsb = 0;// 断言长度为16位assert data.length == 16 : "data must be 16 bytes in length";for (int i=0; i<8; i++)msb = (msb << 8) | (data[i] & 0xff);for (int i=8; i<16; i++)lsb = (lsb << 8) | (data[i] & 0xff);this.mostSigBits = msb;this.leastSigBits = lsb;}// 有参构造public UUID(long mostSigBits, long leastSigBits) {this.mostSigBits = mostSigBits;this.leastSigBits = leastSigBits;}// 静态方法 使用最多的方法public static UUID randomUUID() {// 使用SecureRandom生成随机数,替换version和variant就是 UUIDSecureRandom ng = Holder.numberGenerator;byte[] randomBytes = new byte[16];ng.nextBytes(randomBytes);randomBytes[6] &= 0x0f; /* clear version */randomBytes[6] |= 0x40; /* set to version 4 */randomBytes[8] &= 0x3f; /* clear variant */randomBytes[8] |= 0x80; /* set to IETF variant */return new UUID(randomBytes);}// 静态工厂检索类型3(基于名称的) UUID的基于指定的字节数组public static UUID nameUUIDFromBytes(byte[] name) {MessageDigest md;try {md = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException nsae) {throw new InternalError("MD5 not supported", nsae);}byte[] md5Bytes = md.digest(name);md5Bytes[6] &= 0x0f; /* clear version */md5Bytes[6] |= 0x30; /* set to version 3 */md5Bytes[8] &= 0x3f; /* clear variant */md5Bytes[8] |= 0x80; /* set to IETF variant */return new UUID(md5Bytes);}// 创建一个UUID如在所描述的字符串标准表示toStrinpublic static UUID fromString(String name) {String[] components = name.split("-");if (components.length != 5)throw new IllegalArgumentException("Invalid UUID string: "+name);for (int i=0; i<5; i++)components[i] = "0x"+components[i];long mostSigBits = Long.decode(components[0]).longValue();mostSigBits <<= 16;mostSigBits |= Long.decode(components[1]).longValue();mostSigBits <<= 16;mostSigBits |= Long.decode(components[2]).longValue();long leastSigBits = Long.decode(components[3]).longValue();leastSigBits <<= 48;leastSigBits |= Long.decode(components[4]).longValue();return new UUID(mostSigBits, leastSigBits);}// 获取低位个数public long getLeastSignificantBits() {return leastSigBits;}// 获取最长的个数public long getMostSignificantBits() {return mostSigBits;}// 获得版本号// 与此相关联的版本号UUID 。 版本号描述这怎么UUID生成。 版本号具有以下含义:// 基于时间的UUID 1// 2 DCE安全UUID// 基于名字的3 UUID// 4随机生成UUIDpublic int version() {// Version is bits masked by 0x000000000000F000 in MS longreturn (int)((mostSigBits >> 12) & 0x0f);}public int variant() {// This field is composed of a varying number of bits.// 0 - - Reserved for NCS backward compatibility// 1 0 - The IETF aka Leach-Salz variant (used by this class)// 1 1 0 Reserved, Microsoft backward compatibility// 1 1 1 Reserved for future definition.return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))& (leastSigBits >> 63));}// 生成时间戳public long timestamp() {if (version() != 1) {throw new UnsupportedOperationException("Not a time-based UUID");}return (mostSigBits & 0x0FFFL) << 48| ((mostSigBits >> 16) & 0x0FFFFL) << 32| mostSigBits >>> 32;}// 与此UUID相关联的时钟序列值public int clockSequence() {if (version() != 1) {throw new UnsupportedOperationException("Not a time-based UUID");}return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);}// 与此UUID相关联的节点的值public long node() {if (version() != 1) {throw new UnsupportedOperationException("Not a time-based UUID");}return leastSigBits & 0x0000FFFFFFFFFFFFL;}// toString方法public String toString() {return (digits(mostSigBits >> 32, 8) + "-" +digits(mostSigBits >> 16, 4) + "-" +digits(mostSigBits, 4) + "-" +digits(leastSigBits >> 48, 4) + "-" +digits(leastSigBits, 12));}// 返回VAL由十六进制数字指定的数来表示。private static String digits(long val, int digits) {long hi = 1L << (digits * 4);return Long.toHexString(hi | (val & (hi - 1))).substring(1);}public int hashCode() {long hilo = mostSigBits ^ leastSigBits;return ((int)(hilo >> 32)) ^ (int) hilo;}public boolean equals(Object obj) {if ((null == obj) || (obj.getClass() != UUID.class))return false;UUID id = (UUID)obj;return (mostSigBits == id.mostSigBits &&leastSigBits == id.leastSigBits);}public int compareTo(UUID val) {return (this.mostSigBits < val.mostSigBits ? -1 :(this.mostSigBits > val.mostSigBits ? 1 :(this.leastSigBits < val.leastSigBits ? -1 :(this.leastSigBits > val.leastSigBits ? 1 :0))));}}
总结
UUID 是指Universally Unique Identifier,翻译为中文是通用唯一识别码,UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的 UUID,就不需考虑数据库创建时的名称重复问题。
- 123e4567-e89b-12d3-a456-426655440000
- xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
- 数字 M的四位表示 UUID 版本,当前规范有5个版本,M可选值为1, 2, 3, 4, 5 ;
- 数字 N的一至四个最高有效位表示 UUID 变体( variant ),有固定的两位10xx因此只可能取值8, 9, a, b
- UUID版本通过M表示,当前规范有5个版本,M可选值为1, 2, 3, 4, 5。这5个版本使用不同算法,利用不同的信息来产生UUID,各版本有各自优势,适用于不同情景。具体使用的信息
- version 1, date-time & MAC address
- version 2, date-time & group/user id
version 3, MD5 hash & namespace
在学习分布式ID生成的时候,会更加详细的讲解UUID
