现在本文也转到了我自己的博客上,地址:月城小馆
Apache Common组件是java开发中常用的工具,其中的common-lang包是java基本数据类型的处理工具,包括数字、字符串、日期时间等多种工具类。
在org.apache.commons.lang包中有一个随机数工具类RandomStringUtils,它是根据指定的字符串数组生成给定长度的随机数的工具类。该累包含较多的方法,所有方法返回的都是随机数字符串。每个方法至少提供一个参数int count,这个参数表示要生成的随机数的长度,最后真正实现这个随机数生成过程的是下面这个方法:
publicstaticStringrandom(intcount,intstart,intend,
booleanletters,booleannumbers,char[] chars, Random random) {
if(count == 0)
return"";
if(count
thrownewIllegalArgumentException(
"Requested random string length "+ count
+" is less than 0.");
}
if((start == 0) && (end == 0)) {
end = 123;
start = 32;
if((!(letters)) && (!(numbers))) {
start = 0;
end = 2147483647;
}
}
StringBuffer buffer =newStringBuffer();
intgap = end - start;
while(count-- != 0) {
charch;
if(chars ==null)
ch = (char) (random.nextInt(gap) + start);
else{
ch = chars[(random.nextInt(gap) + start)];
}
if(((letters) && (numbers) && (Character.isLetterOrDigit(ch)))
|| ((letters) && (Character.isLetter(ch)))
|| ((numbers) && (Character.isDigit(ch)))
|| ((!(letters)) && (!(numbers))))
buffer.append(ch);
else{
++count;
}
}
returnbuffer.toString();
}
其中的参数:
@paramcount表示要生成的随机数长度
@paramstart开始位置
@paramend结束位置
@paramletters是否包含字母
@paramnumbers是否包含数字
@paramchars指定的字符种子
@paramrandomRandom实例
看代码里面的逻辑很清楚了,别的参数不做讨论,只看chars这个参数。
(1)如果指定了这个参数,则生成的随机数只能包含这个数组里的字符(字符或者数字);
(2)如果没有指定这个数组,传进来的是null,则根据指定的start和end给出随机数,然后在后面的while循环里判断,见红色字体部分。
使用下面这个语句进行调用:
String strLen = RandomStringUtils.random(2, 6, 11, false, true);
这个语句最终调用的还是上面说的那个方法,执行时是死循环状态,问题就出在这里(2)的情况里,如果指定参数letters为false,参数numbers为true,指定的start和end在可见字符之外,比如start=6,end=11,则红色标志部分的代码判断一直为false,造成while进入死循环状态。
为避免这种情况产生,需要在传递参数时小心谨慎,给出合法的起止位置,最好给出字符串数组,指定该方法使用给定的字符生成随机数;或者对这个方法进行完善,定义自己的随机数工具类。