可以借助数据库主键或redis的incr


/**
 * 自定义进制(排除0,1,o,l)
 */
private static final char[] CUSTOM = new char[]{'Q', 'W', 'E', '8', 'A', 'S', '2', 'D', 'Z', 'X', '9', 'C', '7', 'P', '5', 'I', 'K', '3', 'M', 'J', 'U', 'F', 'R', '4', 'V', 'Y', 'L', 'T', 'N', '6', 'B', 'G'};

/**
 * 不能与自定义进制有重复
 */
private static final char FLAG = 'H';

/**
 * 进制长度
 */
private static final int LENGTH = CUSTOM.length;

/**
 * 序列最小长度
 */
private static final int MINLENGTH = 6;

/**
 * 根据ID生成六位随机码
 * @return 随机码
 */
public static String generateCode(long id) {
    char[] buf = new char[32];
    int charPos = 32;

    while ((id / LENGTH) > 0) {
        int ind = (int) (id % LENGTH);
        buf[--charPos] = CUSTOM[ind];
        id /= LENGTH;
    }
    buf[--charPos] = CUSTOM[(int) (id % LENGTH)];
    String str = new String(buf, charPos, (32 - charPos));
    // 不够长度的自动随机补全
    if (str.length() < MINLENGTH) {
        StringBuilder sb = new StringBuilder();
        sb.append(FLAG);
        Random rnd = new Random();
        for (int i = 1; i < MINLENGTH - str.length(); i++) {
            sb.append(CUSTOM[rnd.nextInt(LENGTH)]);
        }
        str += sb.toString();
    }
    return str;
}

public static long codeToId(String code) {
    char chs[] = code.toCharArray();
    long res = 0L;
    for (int i = 0; i < chs.length; i++) {
        int ind = 0;
        for (int j = 0; j < LENGTH; j++) {
            if (chs[i] == CUSTOM[j]) {
                ind = j;
                break;
            }
        }
        if (chs[i] == FLAG) {
            break;
        }
        if (i > 0) {
            res = res * LENGTH + ind;
        } else {
            res = ind;
        }
    }
    return res;
}

public static void main(String[] args) {
    Set<String> stringSet = new HashSet<>();
    for (int i = 0; i < 1000000; i++) {
        stringSet.add(generateCode(i));
    }
    System.out.println(stringSet.size());
}