22位/32位UUID
32 位的 UUID,最常见的代码:UUID.randomUUID().toString().replace("-",""),
其实可以直接使用 Long.toHexString(),只是过程需要注意,1L 的 16 进制数也是1,不满足 32 位的要补0;
22 位 UUID,就是将 128 位的 2 进制的 UUID 转为 64 进制,实现进制转换函数即可。
/* * MIT License * * Copyright (c) 2019 Mr.css * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ package cn.seaboot.commons.core; import cn.seaboot.commons.digest.Base64; import java.util.UUID; /** * 设备号 * * @author ChenSS 2018年7月13日 上午11:20:38 */ public class UUIDUtils { private UUIDUtils() { } /** * 生成UUID * * @return uuid */ public static String genUUID() { return UUID.randomUUID().toString(); } /** * 生成 32 位 UUID * * <p> * Returns a {@code String} object representing this {@code UUID}. * * <p> The UUID string representation is as described by this BNF: * <blockquote><pre> * {@code * UUID = <time_low><time_mid> * <time_high_and_version> * <variant_and_sequence> * time_low = 4*<hexOctet> * time_mid = 2*<hexOctet> * time_high_and_version = 2*<hexOctet> * variant_and_sequence = 2*<hexOctet> * node = 6*<hexOctet> * hexOctet = <hexDigit><hexDigit> * hexDigit = * "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" * | "a" | "b" | "c" | "d" | "e" | "f" * | "A" | "B" | "C" | "D" | "E" | "F" * }</pre></blockquote> * * @return A string representation of this {@code UUID} */ public static String genUUID32() { UUID uuid = UUID.randomUUID(); long mostSigBits = uuid.getMostSignificantBits(); long leastSigBits = uuid.getLeastSignificantBits(); return (digits(mostSigBits >> 32) + digits(mostSigBits) + digits(leastSigBits >> 32) + digits(leastSigBits)); } /** * 二进制 1 后面跟 32 个 0 */ private static final long HI = 1L << (8 * 4); /** * Returns val represented by the specified number of hex digits. */ private static String digits(long val) { long hi = HI; return Long.toHexString(hi | (val & (hi - 1))).substring(1); } /** * 生成32位UUID * <p> * 如果仅用于生成32为UUID,更优的函数是{@link #genUUID32()} * <p> * 此函数用于{@link UUID#toString()}结果的转换。 * <p> * old version: * uuid.substring(0, 8) + uuid.substring(9, 13) + uuid.substring(14, 18) + uuid.substring(19, 23) + uuid.substring(24) * <p> * 执行效率与历史版本性基本一致,新版代码减少了创建对象的次数。 * * @return uuid */ public static String toUUID32(String uuid) { StringBuilder sb = new StringBuilder(32); char ch; for (int i = 0; i < uuid.length(); i++) { ch = uuid.charAt(i); if (ch != '-') { sb.append(ch); } } return sb.toString(); } /** * 生成 22 位 UUID * <p> * base64 算法:8 位二进制数,转为 1 个字节,128 位正好 16 字节, * 16 字节产生 24位 base64 字符串,去除占位 2 个字母,正好 22 位。 * * @return uuid */ public static String base64UUID() { UUID uuid = UUID.randomUUID(); long msb = uuid.getMostSignificantBits(); long lsb = uuid.getLeastSignificantBits(); int x; byte[] buffer = new byte[16]; for (int i = 0; i < 8; i++) { x = 8 * (7 - i); buffer[i] = (byte) (int) (msb >> x); buffer[i + 8] = (byte) (int) (lsb >> x); } return Base64.encodeString(buffer).substring(0, 22); } /** * 生成 22 位 UUID * <p> * UUID 128位,每 6 位用一个 64 进制字符表示,正好 22 位。 * 此函数采用的是 64 进制转换,而不是 Base64 编码,因为 128 不能被 6 整除,第 11 位和第 22 位,只能是字母。 * <p> * 将数字转为 * * @return uuid */ public static String genUUID22() { UUID uuid = UUID.randomUUID(); long msb = uuid.getMostSignificantBits(); long lsb = uuid.getLeastSignificantBits(); int x; char[] buffer = new char[22]; for (int i = 0; i < 11; i++) { x = 6 * (10 - i); buffer[i] = digits64((int) (msb >> x)); buffer[i + 11] = digits64((int) (lsb >> x)); } return new String(buffer); } /** * Returns val represented by the specified number of 64 digits. */ private static char digits64(int val) { return CHARS[val & 63]; } /** * 生成 8 位 UUID 标识码 * <p> * 作为唯一 ID 使用的时候,很明显,长度不够,必定会出现重复, * 但是可以作为 uuid 的标识码使用,类似于数字签名,如果 uuid 被篡改,生成的标识码会发生变化。 * * @param uid 32 位 uuid * @return uuid 标识码 */ public static String toUUID8(String uid) { StringBuilder shortBuffer = new StringBuilder(); for (int i = 0; i < 8; i++) { String str = uid.substring(i * 4, i * 4 + 4); int x = Integer.parseInt(str, 16); shortBuffer.append(CHARS[x & 61]); } return shortBuffer.toString(); } private final static char[] CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; }
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!