随机数工具类

安利一个随机数生成工具类

package com.joincheer.jcp.utils;

import java.util.Random;

/**
 * 随机数生成工具
 */
public final class UniqueCodeUtils {
    private static final int NUMBER = 0;

    private static final int UPPER = 1;

    private static final int LOWER = 2;

    private static final int SPECIAL = 3;

    private static final int UNDERLINE = 4;

    private static final int SPACE = 5;

    private static final String[] seedTypes = new String[]{
            "NUMBER", "UPPER", "LOWER", "SPECIAL", "UNDERLINE", "SPACE"
    };

    private static final Random random = new Random();

    private static int SEED_TYPES_LENGTH = seedTypes.length;

    private static char[][] rootSeeds = new char[SEED_TYPES_LENGTH][];

    static {
        StringBuffer sb = new StringBuffer(95);
        for (int i = 48; i < 58; i ++) {
            sb.append((char)i);
        }
        for (int i = 65; i < 91; i ++) {
            sb.append((char)i);
        }
        for (int i = 97; i < 123; i ++) {
            sb.append((char)i);
        }
        for (int i = 33; i < 48; i ++) {
            sb.append((char)i);
        }
        for (int i = 58; i < 65; i ++) {
            sb.append((char)i);
        }
        for (int i = 91; i < 95; i ++) {
            sb.append((char)i);
        }
        for (int i = 96; i < 97; i ++) {
            sb.append((char)i);
        }
        for (int i = 123; i < 127; i ++) {
            sb.append((char)i);
        }
        for (int i = 95; i < 96; i ++) {
            sb.append((char)i);
        }
        for (int i = 32; i < 33; i ++) {
            sb.append((char)i);
        }
        String seedStr = sb.toString();

        rootSeeds[NUMBER] = seedStr.substring(0, 10).toCharArray();

        rootSeeds[UPPER] = seedStr.substring(10, 36).toCharArray();

        rootSeeds[LOWER] = seedStr.substring(36, 62).toCharArray();

        rootSeeds[SPECIAL] = seedStr.substring(62, 93).toCharArray();

        rootSeeds[UNDERLINE] = new char[]{seedStr.charAt(93)};

        rootSeeds[SPACE] = new char[]{seedStr.charAt(94)};

    }

    /**
     * 交换数组中两个字符位置
     * @param chars
     * @param a
     * @param b
     */
    private static void swap(char[] chars, int a, int b) {
        char t;
        t = chars[a];
        chars[a] = chars[b];
        chars[b] = t;
    }

    /**
     * 验证字符数组中是否包含指定字符
     * @param chars
     * @param a
     * @return
     */
    private static boolean hasChar(char[] chars, char a) {
        for (int i = 0; i < chars.length; i ++) {
            if (chars[i] == a) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据指定的每种字符类型数量生成表达式
     * @param typesNum
     * @return
     */
    private static int[][] createRules(int... typesNum) {
        return new int[][]{
                {NUMBER, typesNum[NUMBER]},
                {UPPER, typesNum[UPPER]},
                {LOWER, typesNum[LOWER]},
                {SPECIAL, typesNum[SPECIAL]},
                {UNDERLINE, typesNum[UNDERLINE]},
                {SPACE, typesNum[SPACE]}
        };
    }

    /**
     * 根据数量规则生成字符种子
     * @param rules {{3, 5}, {4, 8}} ==> {{"类型LOWER", "5个"}, {"类型UNDERLINE", "8个"}}
     * @return
     */
    private static char[] generateSeeds(int[][] rules) {
        StringBuffer sb = new StringBuffer();
        for (int[] rule : rules) {
            for (int i = 0; i < rule[1]; i ++) {
                sb.append(rootSeeds[rule[0]][random.nextInt(rootSeeds[rule[0]].length)]);
            }
        }
        return sb.toString().toCharArray();
    }

    /**
     * 根据指定条件生成随机字符串通用方法一
     * @param needBeginWithLetter 指定是否需要以字母开头
     * @param typesNum 按顺序指定所有字符类型个数
     * @return
     */
    private static String generate(boolean needBeginWithLetter, int... typesNum){

        char[] seeds = generateSeeds(createRules(typesNum));
        for (int i = 0; i < seeds.length; i ++) {
            int randomIndex = random.nextInt(seeds.length);
            if (randomIndex != i) {
                swap(seeds, i, randomIndex);
            }
        }
        if (needBeginWithLetter && !hasChar(rootSeeds[UPPER], seeds[0]) && !hasChar(rootSeeds[LOWER], seeds[0])) {

            for (int i = 1; i < seeds.length; i ++) {
                if (hasChar(rootSeeds[UPPER], seeds[i]) || hasChar(rootSeeds[LOWER], seeds[i])) {
                    swap(seeds, 0, i);
                    break;
                }
            }
        }
        return String.valueOf(seeds);
    }

    /**
     * 根据指定条件生成随机字符串通用方法二
     * @param length 指定字符个数
     * @param needBeginWithLetter 指定是否需要以字母开头
     * @param hasTypes 按顺序指定所有字符类型是否需要
     * @return
     */
    private static String generate(int length, boolean needBeginWithLetter, boolean... hasTypes){
        int[] typesNum = new int[SEED_TYPES_LENGTH];
        if (needBeginWithLetter && hasTypes[UPPER]) {
            typesNum[UPPER] ++;
            length --;
        }else if (needBeginWithLetter && hasTypes[LOWER]) {
            typesNum[LOWER] ++;
            length --;
        }
        int checkedNum = 0;
        for (int i = 0; i < hasTypes.length; i ++) {
            if (hasTypes[i]) {
                checkedNum ++;
            }
        }
        for (int i = 0; i < length; i ++) {
            int k = 0, r = random.nextInt(checkedNum);
            for (int j = 0; j < hasTypes.length; j ++) {
                if (hasTypes[j]) {
                    if (r == k) {
                        typesNum[j] ++;
                        break;
                    }
                    k ++;
                }
            }
        }
        return generate(needBeginWithLetter, typesNum);
    }

    /**
     * 生成一个由32个字符长度的随机字符串,
     * 该字符串由数字和小写字母构成
     * @return
     */
    public static String genUniqueID() {
        boolean[] hasTypes = new boolean[SEED_TYPES_LENGTH];
        hasTypes[NUMBER] = true;
        hasTypes[LOWER] = true;
        return generate(32, false, hasTypes);
    }

    /**
     * 生成指定长度的随机字符串,
     * 该字符串由数字和小写字母构成。
     * @param length
     * @return
     */
    public static String genUniqueID(int length) {
        boolean[] hasTypes = new boolean[SEED_TYPES_LENGTH];
        hasTypes[NUMBER] = true;
        hasTypes[LOWER] = true;
        return generate(32, false, hasTypes);
    }

    /**
     * 生成一个长度为8个字符的字符串,
     * 该字符串仅有数字和大写字母构成,
     * 且该字符串由大写字母开头。
     * @return
     */
    public static String genShortUID() {
        boolean[] hasTypes = new boolean[SEED_TYPES_LENGTH];
        hasTypes[NUMBER] = true;
        hasTypes[UPPER] = true;
        return generate(8, true, hasTypes);
    }

    /**
     * 生成一个长度为8个字符的随机密码,
     * 该密码由数字和大小写字母构成。
     * @return
     */
    public static String genPWD() {
        boolean[] hasTypes = new boolean[SEED_TYPES_LENGTH];
        hasTypes[NUMBER] = true;
        hasTypes[UPPER] = true;
        hasTypes[LOWER] = true;
        return generate(8, false, hasTypes);
    }

    /**
     * 生成一个长度为8个字符的随机密码,
     * 该密码由数字、大写字母、小写字母和特殊字符构成。
     * @return
     */
    public static String genDifficultPWD() {
        boolean[] hasTypes = new boolean[SEED_TYPES_LENGTH];
        hasTypes[NUMBER] = true;
        hasTypes[UPPER] = true;
        hasTypes[LOWER] = true;
        hasTypes[SPECIAL] = true;
        return generate(10, false, hasTypes);
    }

    /**
     * 生成一个简单的6位数字组成的密码
     * @return
     */
    public static String genSimplePWD() {
        boolean[] hasTypes = new boolean[SEED_TYPES_LENGTH];
        hasTypes[NUMBER] = true;
        return generate(6, false, hasTypes);
    }

    public static void main(String[] args) {
        System.out.println("------------genUniqueID--------------");
        for (int i = 0; i < 20; i ++) {
            String randomStr = genUniqueID();
            System.out.println(randomStr);
        }
        System.out.println("------------genShortUID--------------");
        for (int i = 0; i < 20; i ++) {
            String randomStr = genShortUID();
            System.out.println(randomStr);
        }
        System.out.println("------------genDifficultPWD--------------");
        for (int i = 0; i < 20; i ++) {
            String randomStr = genDifficultPWD();
            System.out.println(randomStr);
        }
        System.out.println("------------genPWD--------------");
        for (int i = 0; i < 20; i ++) {
            String randomStr = genPWD();
            System.out.println(randomStr);
        }
        System.out.println("------------genSimplePWD--------------");
        for (int i = 0; i < 20; i ++) {
            String randomStr = genSimplePWD();
            System.out.println(randomStr);
        }

    }

}


------------genUniqueID--------------
nly17s6cj70sfyg29r4t70o13n35fur2
725408jdjh62aw183u15tp227sep215k
4sm8e449f031lhls82pf4uy60gzb7613
1ldeqxw7f2lj414dclmisgz2k2g5h454
2db7g5001obc9l39020g2v3h370eh6bb
np1fc34vhw13gz80stfuuy02w92leb1c
uoa8hr5089wcc87729b96wcpi1v37e06
2a529u64338576i99ipd00yi8bqrp4s6
1a39h95n68l6dx279bxh12731l7xks6t
0koxm0162487sxmy21hvix0hr0o5sp6c
g96g81u364i89m0vc2q52c38so89f903
7cabo88p88thje95r7rno86h981oxs74
74ga19z7b781q5pz082janny7w6r046w
vd9ms1b7g510dx90r44x40dm182z799g
0ln9a4eh281yx41uaw2nsz3spo2c08ox
7l9we4431l435jyl3856jaw8963dd043
42o7601jzi1i4ga44354t2pqb1dlq8l2
216h53vd779p2c82x966bvd8158kya00
09794m974y0pblwoy7z5jm17n5679xr1
b8e651o464j151gr4a56pu8ey21tyu53
------------genShortUID--------------
B658043D
C6216YOR
BJ9OE126
NWGUOU2U
K93399R3
KCH34OW9
S89CY28O
M171M5U4
ZHLBKH08
G1TC215V
S485IN12
BQ14ZMHC
CHZ9YJ6V
B10II1NA
LDSWNI8E
X1I8K6KY
TVNM685D
R25WQ854
C9507RX4
P34942F0
------------genDifficultPWD--------------
%8Cl2j6&6x
VO0=ibC60r
j)j5iE4X+H
W#6h2Ub%4L
$.M/~$pc0V
ckw3x,5SE`
YiR43K0/$U
E9|0I7gB;K
0PbG@]ytke
:Gv^A<i703
D6HE<7g+g}
L03w8RJ5h5
n3"69:Hvz=
z1r5|3=g>)
"Y5OiH32lN
l*T?lJ\8S,
hGG582=vY2
MsX0[:=2Uh
c(eDT59{2A
h5nYpHo~3t
------------genPWD--------------
83kWMdbT
B0liAEMB
1cJ94BG4
1y3WhYJI
6lB4Ixh4
cngU6UyD
y96x0F2o
35UN32aU
50anHR9V
4L5IbZHX
3RpVMso1
q39z9082
5MGVrg5Z
PxKkis1L
E8k3DhhR
O9r9oAY7
OL6Ia00v
K8WRAELU
o32XomdR
W9V7Bi64
------------genSimplePWD--------------
102026
678238
132513
501585
644916
651972
947663
889635
720145
989735
326783
423419
171370
873213
430180
155725
894655
178177
669052
437313
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值