Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.dadiyang.random.RANDOM Maven / Gradle / Ivy
package com.github.dadiyang.random;
import com.alibaba.fastjson.JSON;
import com.github.dadiyang.mockjs.Mock;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.text.RandomStringGenerator;
import org.jeasy.random.EasyRandom;
import org.jeasy.random.EasyRandomParameters;
import org.jeasy.random.api.Randomizer;
import org.jeasy.random.api.RandomizerRegistry;
import org.jeasy.random.randomizers.RegularExpressionRandomizer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.*;
/**
* 随机工具,封装 ThreadLocalRandom 提供的常规类型随机生成方法和 EasyRandom 提供的对象和 List 的随机生成方法
*
* @author dadiyang
* @since 2021/2/11
*/
public class RANDOM {
/**
* 这个正则不是完整的身份证校验逻辑,只生成前面符合条件的 17 位数字
* * 生日部分取了 1930-2019,我们尽最大可能地让生成的身份证号符合校验规则
* * 不包含最后一位
*/
private static final String ID_CARD_REG_WITHOUT_VERIFY_CODE = "^(12|11|13|14|15|21|22|23|31|32|33|34|35|36|37|41|42|43|44|45|46|50|51|52|53|54|61|62|63|64|65|71|81|82|91)\\d{4}(19[3-9][0-9]|20[01][0-9])((0[1-9])|(10|11|12))(([0-2][1-8])|10|20)\\d{3}$";
/**
* 身份证前 16 位,用于指定性别
*/
private static final String ID_CARD_PRE_16_REG = "^(12|11|13|14|15|21|22|23|31|32|33|34|35|36|37|41|42|43|44|45|46|50|51|52|53|54|61|62|63|64|65|71|81|82|91)\\d{4}(19[3-9][0-9]|20[01][0-9])((0[1-9])|(10|11|12))(([0-2][1-8])|10|20)\\d{2}$";
/**
* 身份证前6位正则
*/
private static final String ID_CARD_PRE_6_REG = "^(12|11|13|14|15|21|22|23|31|32|33|34|35|36|37|41|42|43|44|45|46|50|51|52|53|54|61|62|63|64|65|71|81|82|91)\\d{4}$";
private static final String[] VERIFY_CODES = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
private static final String[] WT = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
private static final EasyRandom easyRandom;
private static final int EVENT_SYMBOL = 2;
private RANDOM() {
throw new UnsupportedOperationException("静态工具类不允许被实例化");
}
static {
EasyRandomParameters param = new EasyRandomParameters();
param.setStringLengthRange(new EasyRandomParameters.Range<>(5, 10));
param.randomizerRegistry(new BigDecimalRegistry());
param.setScanClasspathForConcreteTypes(true);
param.setObjectPoolSize(100);
param.setIgnoreRandomizationErrors(true);
// 我们通过修改 EasyRandom 的源码,支持单个字段生成出错时忽略该字段
param.setIgnoreRandomizationFieldErrors(true);
param.setRandomizationDepth(10);
easyRandom = new EasyRandom(param);
}
/**
* 根据给定的类型生成一个随机的对象
*/
public static T nextObject(Class clz) {
return easyRandom.nextObject(clz);
}
/**
* 根据给定的 mockjs 模板生成一个随机的对象
*/
public static T nextObjectWithMockJs(String tpl, Class clz) {
return Mock.mock(tpl, clz);
}
/**
* 根据给定的类型和大小生成一个随机对象的列表
*/
public static List nextList(Class clz, int size) {
return objects(clz, size).collect(Collectors.toList());
}
/**
* 根据给定的 mockjs 模板生成一个随机对象的列表
*/
@SuppressWarnings("unchecked")
public static List nextListWithMockJs(String script, Class clz, int size) {
List> list = Mock.mockList(script, size);
return JSON.parseArray(JSON.toJSONString(list), clz);
}
/**
* 根据给定的类型和大小生成一个随机对象的集合
*/
public static Set nextSet(Class clz, int size) {
return objects(clz, size).collect(Collectors.toSet());
}
/**
* 根据给定的 mockjs 模板生成一个随机对象的集合
*/
@SuppressWarnings("unchecked")
public static Set nextSetWithMockJs(String script, Class clz, int size) {
return new HashSet<>(nextListWithMockJs(script, clz, size));
}
/**
* 根据给定的类型和大小生成一个随机对象流
*/
public static Stream objects(Class clz, int size) {
return easyRandom.objects(clz, size);
}
/**
* 随机字符串,只包含字母和数字
*/
public static String nextString(int length) {
return new RandomStringGenerator.Builder().withinRange(new char[]{'a', 'z'}, new char[]{'A', 'Z'}, new char[]{'0', '9'}).build().generate(length);
}
/**
* 根据正则表达式生成随机字符串
*
* @param reg 正则表达式
*/
public static String nextStringWithReg(String reg) {
return new RegularExpressionRandomizer(reg, nextLong()).getRandomValue();
}
/**
* 根据正则表达式生成随机字符串
*
* @param reg 正则表达式
* @param size 数量
*/
public static List nextStringsWithReg(String reg, int size) {
if (size == 0) {
return Collections.emptyList();
}
RegularExpressionRandomizer randomizer = new RegularExpressionRandomizer(reg, nextLong());
List rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
rs.add(randomizer.getRandomValue());
}
return rs;
}
/**
* 随机生成一个身份证号
*/
public static String nextIdCard() {
String card = nextStringWithReg(ID_CARD_REG_WITHOUT_VERIFY_CODE).substring(0, 17);
return card + computeVerifyCode(card);
}
/**
* 随机生成一个身份证号
*
* @param age 指定该身份证号的年龄
*/
public static String nextIdCardWithAge(int age) {
String card = nextStringWithReg(ID_CARD_PRE_6_REG);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - age);
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
card += new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
card += nextInt(100, 999);
return card + computeVerifyCode(card);
}
/**
* 随机生成一个身份证号
*
* @param gender 指定性别,奇数男,偶数女
*/
public static String nextIdCardWithGender(int gender) {
String card = nextStringWithReg(ID_CARD_PRE_16_REG);
card += (gender % 10);
return card + computeVerifyCode(card);
}
/**
* 随机生成一个男性的随机身份证号
*/
public static String nextMaleIdCard() {
return nextIdCardWithAgeAndGender(nextInt(0, 100), Math.abs(nextOddNumber()) % 10);
}
/**
* 随机生成一个指定年龄的男性的随机身份证号
*/
public static String nextMaleIdCard(int age) {
return nextIdCardWithAgeAndGender(age, Math.abs(nextOddNumber()) % 10);
}
/**
* 随机生成一个女性的随机身份证号
*/
public static String nextFemaleIdCard() {
return nextIdCardWithAgeAndGender(nextInt(0, 100), Math.abs(nextEvenNumber()) % 10);
}
/**
* 随机生成一个指定年龄的女性的随机身份证号
*/
public static String nextFemaleIdCard(int age) {
return nextIdCardWithAgeAndGender(age, Math.abs(nextEvenNumber()) % 10);
}
/**
* 随机生成一个身份证号
*
* @param age 指定年龄
* @param gender 指定性别,奇数男,偶数女
*/
public static String nextIdCardWithAgeAndGender(int age, int gender) {
String card = nextStringWithReg(ID_CARD_PRE_6_REG);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - age);
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
card += new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
card += nextInt(10, 99);
card += (gender % 10);
return card + computeVerifyCode(card);
}
/**
* 随机生成一批身份证号
*/
public static List nextIdCards(int size) {
List arr = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
arr.add(nextIdCard());
}
return arr;
}
/**
* 判断第18位校验码是否正确
* 第18位校验码的计算方式:
* 1. 对前17位数字本体码加权求和
* 公式为:S = Sum(Id[i]* WT[i]), i = 0, ... , 16
* 其中Id表示第i个位置上的身份证号码数字值,Wi表示第i位置上的加权因子,其各位对应的值依次为: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
* 2. 用11对计算结果取模
* Y = mod(S, 11)
* 3. 根据模的值得到对应的校验码
* 对应关系为:
* Y值: 0 1 2 3 4 5 6 7 8 9 10
* 校验码: 1 0 X 9 8 7 6 5 4 3 2
*/
private static String computeVerifyCode(String id) {
int sum = 0;
for (int i = 0; i < 17; i++) {
sum = sum + Integer.parseInt(String.valueOf(id.charAt(i))) * Integer.parseInt(WT[i]);
}
int modValue = sum % 11;
return VERIFY_CODES[modValue];
}
/**
* 随机奇数
*/
public static int nextOddNumber() {
return nextEvenNumber() + 1;
}
/**
* 随机偶数
*/
public static int nextEvenNumber() {
int i = nextInt();
if (i % EVENT_SYMBOL == 0) {
return i;
} else {
return i + 1;
}
}
/**
* 随机字符串列表,只包含字母和数字
*/
public static List nextStrings(int minLength, int maxLength, int size) {
List strings = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
strings.add(nextString(minLength, maxLength));
}
return strings;
}
public static String nextString(int minLength, int maxLength) {
return new RandomStringGenerator.Builder().withinRange(new char[]{'a', 'z'}, new char[]{'A', 'Z'}, new char[]{'0', '9'}).build().generate(minLength, maxLength);
}
public static String nextStringIn(String... values) {
if (values.length <= 0) {
throw new IllegalArgumentException("values不能为空");
}
return values[nextInt(0, values.length)];
}
/**
* 随机生成一个枚举
*/
public static > E nextEnum(final Class enumClass) {
List list = EnumUtils.getEnumList(enumClass);
return EnumUtils.getEnum(enumClass, nextStringIn(list.stream().map(Enum::name).toArray(String[]::new)));
}
/**
* 随机生成一个枚举值
*/
public static > String nextEnumValue(final Class enumClass) {
List list = EnumUtils.getEnumList(enumClass);
return nextStringIn(list.stream().map(Enum::name).toArray(String[]::new));
}
/**
* 随机生成一批枚举值
*/
public static > List nextEnumValues(final Class enumClass, int size) {
List list = EnumUtils.getEnumList(enumClass);
return nextStringsIn(size, list.stream().map(Enum::name).toArray(String[]::new));
}
public static List nextStringsIn(int size, String... values) {
if (values.length <= 0 || size <= 0) {
throw new IllegalArgumentException("values不能为空且size必须大于0");
}
List rs = new LinkedList<>();
for (int i = 0; i < size; i++) {
rs.add(nextStringIn(values));
}
return rs;
}
/**
* 随机汉字
*/
public static String nextChineseString(int length) {
return new RandomStringGenerator.Builder().withinRange(new char[]{0x4e00, 0x9fa5}).build().generate(length);
}
/**
* 随机汉字
*/
public static String nextChineseString(int minLength, int maxLength) {
return new RandomStringGenerator.Builder().withinRange(new char[]{0x4e00, 0x9fa5}).build().generate(minLength, maxLength);
}
public static int nextInt() {
return ThreadLocalRandom.current().nextInt();
}
public static int nextInt(int bound) {
return ThreadLocalRandom.current().nextInt(bound);
}
public static int nextInt(int origin, int bound) {
return ThreadLocalRandom.current().nextInt(origin, bound);
}
public static long nextLong() {
return ThreadLocalRandom.current().nextLong();
}
public static long nextLong(long bound) {
return ThreadLocalRandom.current().nextLong(bound);
}
public static long nextLong(long origin, long bound) {
return ThreadLocalRandom.current().nextLong(origin, bound);
}
public static double nextDouble() {
return ThreadLocalRandom.current().nextDouble();
}
public static double nextDouble(double bound) {
return ThreadLocalRandom.current().nextDouble(bound);
}
public static double nextDouble(double origin, double bound) {
return ThreadLocalRandom.current().nextDouble(origin, bound);
}
public static boolean nextBoolean() {
return ThreadLocalRandom.current().nextBoolean();
}
public static float nextFloat() {
return ThreadLocalRandom.current().nextFloat();
}
public static double nextGaussian() {
return ThreadLocalRandom.current().nextGaussian();
}
public static IntStream ints(long streamSize) {
return ThreadLocalRandom.current().ints(streamSize);
}
public static IntStream ints() {
return ThreadLocalRandom.current().ints();
}
public static IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
return ThreadLocalRandom.current().ints(streamSize, randomNumberOrigin, randomNumberBound);
}
public static IntStream ints(int randomNumberOrigin, int randomNumberBound) {
return ThreadLocalRandom.current().ints(randomNumberOrigin, randomNumberBound);
}
public static LongStream longs(long streamSize) {
return ThreadLocalRandom.current().longs(streamSize);
}
public static LongStream longs() {
return ThreadLocalRandom.current().longs();
}
public static LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) {
return ThreadLocalRandom.current().longs(streamSize, randomNumberOrigin, randomNumberBound);
}
public static LongStream longs(long randomNumberOrigin, long randomNumberBound) {
return ThreadLocalRandom.current().longs(randomNumberOrigin, randomNumberBound);
}
public static DoubleStream doubles(long streamSize) {
return ThreadLocalRandom.current().doubles(streamSize);
}
public static DoubleStream doubles() {
return ThreadLocalRandom.current().doubles();
}
public static DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
return ThreadLocalRandom.current().doubles(streamSize, randomNumberOrigin, randomNumberBound);
}
public static DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
return ThreadLocalRandom.current().doubles(randomNumberOrigin, randomNumberBound);
}
public static void nextBytes(byte[] bytes) {
ThreadLocalRandom.current().nextBytes(bytes);
}
private static class BigDecimalRandomizer implements Randomizer {
@Override
public BigDecimal getRandomValue() {
return BigDecimal.valueOf(nextDouble(0L, Integer.MAX_VALUE))
.setScale(nextInt(0, 2), BigDecimal.ROUND_HALF_UP);
}
}
/**
* 默认生成的 BigDecimal 实例精度过大,将会导致用于插入数据库时超过精度而报错,所以我们默认精度取为 0 到 2
*/
private static class BigDecimalRegistry implements RandomizerRegistry {
static final BigDecimalRandomizer bigDecimalRandomizer = new BigDecimalRandomizer();
@Override
public void init(EasyRandomParameters easyRandomParameters) {
}
@Override
public Randomizer> getRandomizer(Field field) {
if (field.getType() == BigDecimal.class) {
return bigDecimalRandomizer;
} else {
return null;
}
}
@Override
public Randomizer> getRandomizer(Class> aClass) {
if (aClass == BigDecimal.class) {
return bigDecimalRandomizer;
} else {
return null;
}
}
}
}