JAVA自带的随机数函数:
Random rd = new Random();
rd.getXXXX();
存在严重的不随机现象,当需要在短时间内大量产生随机数时,该方法并不可靠,特别是用于产生默认密码,很容易重复或者被破解。
一般的验证码是数字和字母结合(摒弃那些容易混淆的如O和0,I和1)
基于以上的字母和数字混合的随机数函数如下:(有缺陷,容易混淆的字符只去掉了O,即随机数是0-9和A-Z不包含O组合而成)
/**
*转成35进制
*用该方法能将long型的参数转成35进制由0-9A-Z不含O组合成的数
*/
//num=36 转换后为11
private static StringBuffer long236HexStr(Long num) {
StringBuffer str = new StringBuffer();
//处理最末位 result=1
int result = (int) (num % 35);
if (result < 10) {
str.append(result);
} else if (result < 24) {
char charResult = (char) (result + 55);
str.append(charResult);
} else {
char charResult = (char) (result + 56);
str.append(charResult);
}
//递归处理 iter=1
Long iter = num / 35;
if (iter != 0) {
str.append(long236HexStr(iter));
}
return str;
}
/**
*转成相应位数的35进制,不足位数左补0
*num为需要转换的long型数,width为需要的最后随机数的长度
*/
public static String long235HexStr(Long num, int width) {
StringBuffer resultBuffer = long236HexStr(num).reverse();
String result = resultBuffer.toString();
int len = result.length();
if (len > width) {
//转成35进制后过长,截取后面需要的位数
return result.substring(len - width);
} else {
//位数不足,左补0
return leftFill0(result, width - len);
}
}
/**
* 取得6位随机数(字母+数字)
*
* @return
*/
public static String getRandCode() {
String reStr = null;
Date dt = new Date();//取得当前时间
// 当前时间减去一个固定时间点取得毫秒数(减去一个固定时间是为了控制time的值不至于过大)
Long time = dt.getTime() - beginDateTime;
AtomicInteger atoNum = new AtomicInteger();
//AtomicInteger类方法,若到某一个值的时候重新设值
//这里是atoNum到MAX_VALUE=1000000的时候重新设成0
atoNum.compareAndSet(MAX_VALUE, 0);
//AtomicInteger类方法,先自加1再取得该值
//这里这么用是确保,在1秒内(即time/1000)也能生成1000000个各部相同的long型数
time = (((long) (time / 1000)) * atoNum.incrementAndGet());
//RAND_CODE_MAX_LONG值为:(long) Math.pow(35, 6);即35的6次方,即随机数最大的值
time %= RAND_CODE_MAX_LONG;
reStr = long235HexStr(time, 6);
return reStr;
}
PS:附带一个简单的左补0方法
//左补0至十位
String autosn = String.format("%010d", "123");//0000000123
或者
/**
* 左补0
* @param param 补位的参数
* @param len 总长度
* @return
*/
private String getParaWithLeftZero(long param, int len){
NumberFormat nf = NumberFormat.getInstance();
//不分组
nf.setGroupingUsed(false);
//设置最大整数位数
nf.setMaximumIntegerDigits(len);
//设置最小整数位数
nf.setMinimumIntegerDigits(len);
return nf.format(param);
}
或者for循环