自定义简化版不重复指定长度随机码生成
Posted 好大的月亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义简化版不重复指定长度随机码生成相关的知识,希望对你有一定的参考价值。
前提
业务中经常需要生成一些不重复的随机码,但是又需要指定长度。这就让现成的UUID
或者雪花算法生成的id
很是捉鸡。
实现
我这边随机码的选择范围是0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
并且长度指定7
位。
我的思路是这样的,既然指定了位数上线,那么肯定是有上限的,62^7
就是它的上限了,一般业务一天用不了这么多,一天千万级别就够了。
所以我打算引入 业务编码 + 时间 + 随机码
来组成这个随机码。
业务编码取固定的3位
其中时间,我打算只取后两位,比如2022
则只用22
,到2099年
这个算法也该换了把。然后将时间年月日
转成62
进制(就是上面的取值范围),可以缩短为3
位数.
剩下的4
位则用random
随机从取值范围数组里取。
代码demo
package com.felix.spring_cloud_one.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
public class RandomCodeGenerateService
@Autowired
private StringRedisTemplate stringRedisTemplate;
List<String> list = new ArrayList<>();
Set<String> set = new HashSet<>();
static String seed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
static String[] split = seed.split("");
public Object randomCodeGenerate(Integer batchSize)
LocalDateTime nowStart = LocalDateTime.now();
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
Month month = now.getMonth();
int dayOfMonth = now.getDayOfMonth();
String yearStr = split[Integer.valueOf(String.valueOf(year).substring(2))];
String monthStr = split[month.getValue()];
String dayOfMonthStr = split[dayOfMonth];
String preFix = yearStr + monthStr + dayOfMonthStr;
//list的key
String redisKey = "randomCodeGenerate" + preFix;
RedisOperations<String, String> operations = stringRedisTemplate.opsForList().getOperations();
BoundListOperations<String, String> boundListOperations = operations.boundListOps(redisKey);
Long size = boundListOperations.size();
List<String> range = boundListOperations.range(0, size);
Set<String> rangeSet = new HashSet<>(range);
Set<String> set = randomStr(rangeSet,4, batchSize, preFix);
ArrayList<String> pushList = new ArrayList<>(set);
int index = 0;
int step = 10000;
int currentIndex = index * step;
int endIndex = (index + 1) * step;
//批量保存到redis
while (endIndex < pushList.size())
List<String> list = pushList.subList(currentIndex, endIndex);
boundListOperations.leftPushAll(list.toArray(new String[]));
index ++;
currentIndex = index * step;
endIndex = (index + 1) * step;
if(currentIndex < pushList.size())
List<String> list = pushList.subList(currentIndex, set.size());
boundListOperations.leftPushAll(list.toArray(new String[]));
System.out.println("list.size:" + this.list.size());
System.out.println("set.size:" + this.set.size());
LocalDateTime nowEnd = LocalDateTime.now();
Duration duration = Duration.between(nowStart, nowEnd);
System.out.println("花费了时间" + duration.toMinutes() + "分钟");
//key过期
stringRedisTemplate.expire(redisKey, 24, TimeUnit.HOURS);
return null;
public Set<String> randomStr(Set<String> historySet,int codeLength, int num, String preFix)
Random random = new Random();
Set<String> set = new HashSet<>();
while (set.size() < num)
String str = "";
for (int i = 0; i < codeLength; i++)
int index = random.nextInt(seed.length());
str += split[index];
if(!CollectionUtils.isEmpty(historySet) && historySet.contains(str))
continue;
if(null != preFix)
str = preFix + str;
set.add(str);
return set;
以上是关于自定义简化版不重复指定长度随机码生成的主要内容,如果未能解决你的问题,请参考以下文章