Apache Common-lang组件里随机数工具类RandomStringUtils的一个bug

来源:互联网 发布:淘宝主页设计多少钱 编辑:程序博客网 时间:2024/06/03 03:53

    现在本文也转到了我自己的博客上,地址:月城小馆

Apache Common组件是java开发中常用的工具,其中的common-lang包是java基本数据类型的处理工具,包括数字、字符串、日期时间等多种工具类。

org.apache.commons.lang包中有一个随机数工具类RandomStringUtils,它是根据指定的字符串数组生成给定长度的随机数的工具类。该累包含较多的方法,所有方法返回的都是随机数字符串。每个方法至少提供一个参数 int count,这个参数表示要生成的随机数的长度,最后真正实现这个随机数生成过程的是下面这个方法:

public static String random(int count, int start, int end,

boolean letters, boolean numbers, char[] chars, Random random) {

if (count == 0)

return "";

if (count < 0) {

throw new IllegalArgumentException(

"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 = new StringBuffer();

int gap = end - start;

while (count-- != 0) {

char ch;

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;

}

}

return buffer.toString();

}

其中的参数:

@param count表示要生成的随机数长度

@param start开始位置

@param end结束位置

@param letters是否包含字母

@param numbers是否包含数字

@param chars指定的字符种子

@param randomRandom实例

看代码里面的逻辑很清楚了,别的参数不做讨论,只看chars这个参数。

(1)如果指定了这个参数,则生成的随机数只能包含这个数组里的字符(字符或者数字);

(2)如果没有指定这个数组,传进来的是null,则根据指定的startend给出随机数,然后在后面的while循环里判断,见红色字体部分。

使用下面这个语句进行调用:

String strLen = RandomStringUtils.random(2, 6, 11, false, true);

这个语句最终调用的还是上面说的那个方法,执行时是死循环状态,问题就出在这里(2)的情况里,如果指定参数lettersfalse,参数numberstrue,指定的startend在可见字符之外,比如start=6end=11,则红色标志部分的代码判断一直为false,造成while进入死循环状态。

为避免这种情况产生,需要在传递参数时小心谨慎,给出合法的起止位置,最好给出字符串数组,指定该方法使用给定的字符生成随机数;或者对这个方法进行完善,定义自己的随机数工具类。

原创粉丝点击