LiiuZeYu_branch
lzy 10 months ago
parent 60e2da7b5b
commit 57cbf1bd64

@ -0,0 +1,127 @@
/*
* Copyright (c) 2018-2999 广 All rights reserved.
*
* https://www.mall4j.com/
*
*
*
*
*/
package com.yami.shop.common.util;
// 导入 Hutool 库中用于生成分布式唯一ID的 Snowflake 类,通常基于雪花算法实现
import cn.hutool.core.lang.Snowflake;
// 导入 Spring 框架用于实现依赖注入的注解以及将类标记为组件的注解,表明该类是受 Spring 管理的组件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* IdUtil
* 1. DICT DICT.length()
* 2. ID便使 ID
* 3. ID ID
* 4. Snowflake ID ID
*
* @author xuliugen
* @date 2018/04/23
*/
@Component
public class IdUtil {
// 通过 Spring 的依赖注入机制,注入一个 Snowflake 实例,用于生成分布式唯一 ID可能用于生成短 ID 的基础)
@Autowired
private Snowflake snowflake;
// 定义了一个包含数字和大小写字母(去除了容易混淆的部分字母)的字符串,作为自定义进制的字符集,用于进制转换操作
private static final String DICT = "0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
// 计算出基于 DICT 字符集的进制数,即字符集的长度,用于进制转换过程中的计算
private static final int SEED = DICT.length();
// 定义了短网址编码的最小长度,用于在生成短网址编码时,如果长度不足则进行补位操作,保证编码长度符合一定要求
private static final int ID_MIN_LENGTH = 6;
/**
* DICT 便
*/
private static final char[] CHARS = DICT.toCharArray();
/**
* Map
*/
private static final Map<Character, Integer> NUMBERS = new HashMap<>();
// 静态代码块,用于初始化 NUMBERS 这个字符到数字的映射 Map遍历 CHARS 字符数组,将每个字符与其对应的索引(在自定义进制下的数字)存入 Map 中
static {
int len = CHARS.length;
for (int i = 0; i < len; i++) {
NUMBERS.put(CHARS[i], i);
}
}
/**
* ID DICT
* SEED DICT
* ID_MIN_LENGTH DICT
*
* @param id ID (1 - 56.8 billion)
* @return "RwTji8""GijT7Y"
*/
public static String encode(long id) {
// 创建一个可变的字符串构建器,用于逐步构建短网址编码字符串
StringBuilder shortUrl = new StringBuilder();
// 当传入的十进制数字大于 0 时,进行进制转换操作,采用除基取余法
while (id > 0) {
// 计算当前十进制数除以自定义进制数SEED的余数将其转换为整数类型该余数将作为在 DICT 中查找对应字符的索引
int r = (int) (id % SEED);
// 将根据余数获取到的对应字符插入到短网址编码字符串的开头(逆序构建编码字符串)
shortUrl.insert(0, CHARS[r]);
// 更新十进制数,将其除以自定义进制数,得到下一轮循环要处理的数字
id = id / SEED;
}
// 获取当前已经构建好的短网址编码字符串的长度
int len = shortUrl.length();
// 如果长度小于最小长度要求ID_MIN_LENGTH进行补位操作
while (len < ID_MIN_LENGTH) {
// 在短网址编码字符串的开头插入 DICT 中的第一个字符(通常是 '0')进行补位
shortUrl.insert(0, CHARS[0]);
// 更新长度
len++;
}
// 返回最终构建好的短网址编码字符串
return shortUrl.toString();
}
/**
* ID
*
*
* @param key "RwTji8""GijT7Y"
* @return ID
*/
public static long decode(String key) {
// 将传入的短网址编码字符串转换为字符数组,方便逐个字符进行处理
char[] shorts = key.toCharArray();
// 获取字符数组的长度,即短网址编码的长度
int len = shorts.length;
// 初始化用于累加计算的十进制数字为 0
long id = 0L;
// 遍历短网址编码的每个字符,从左到右(按照权重从高到低)进行解析计算
for (int i = 0; i < len; i++) {
// 根据当前字符在 NUMBERS 映射 Map 中获取其对应的数字在自定义进制下的数字表示并乘以当前位置对应的权重SEED 的幂次方),然后累加到结果中
id = id + (long) (NUMBERS.get(shorts[i]) * Math.pow(SEED, len - i - 1));
}
// 返回解析得到的十进制数字(数据库记录 ID
return id;
}
/**
* Snowflake ID ID
* ID
*
* @return ID ID
*/
public String nextShortId() {
return encode(snowflake.nextId());
}
}
Loading…
Cancel
Save