JAVA生成指定位数不重复的随机数,随机数含0-9、A-Z

首页 / 新闻资讯 / 正文

琢磨了一晚上,就为了写一个“不重复的随机码生成函数”,生成格式包含0-9,a-z。

头脑风暴,异想天开,写下了如下算法,看上去很高大上的一个随机生成方法。

原理先产生一个UUID,再根据UUID生成一个随机数,UUID,不重复嘛。一测试,坑爹了,生成100万条长度为4的随机码,重复率达到25%,傻眼了。

/**  * 随机码生成  * @author Mo  *   * @param length 随机码长度  * @return  */ public static String random1(int length){ 	/* 	 * 这里直接数字代替,没用uuid.length() 	 * */ 	String uuid = UUID.randomUUID().toString().replace("-", ""); 	 	int len = uuid.length(); 	 	/*定义随机码字符串变量,初始化为""*/ 	String random = ""; 	 	/* 	 * 循环截取UUID 	 * len/length 每次循环截取的字符串长度 	 * len%length 如果出现32长度除不尽的情况,取余数 	 * */ 	int subLen = len/length; 	int remainder = len%length; 	 	/*定义substring的两个参数*/ 	int start = 0,end = 0; 	for(int i=0;i<length;i++){ 		/* 		 * 计算start和end的值 		 * 这里涉及两种方法,一种是除不尽的时候,将截取长度分散到头部,一种是分散到尾部 		 *  		 * uuid的前部分是时间戳构成的,因此前部分截取越少,重复率越底 		 * 固本方法采用了将多余的部分分散到尾部 		 * */ 		/*分散到尾部,如length为7的时候4,4,4,4,5,5,5*/ //			end = start + (length-i <= remainder ? 1 : 0)+subLen; 		/*分散到头部,如length为7 的时候5,5,5,5,4,4,4*/ 		end = start + (i < remainder ? 1 : 0)+subLen; 		/*截取到的字符串*/ 		String code = uuid.substring(start,end); 		/*对所截取的长度进行16位求和*/ 		int count = 0; 		for(char c : code.toCharArray()){ 			count += Integer.valueOf(String.valueOf(c),16); 		} 		/*将求和结果转化成36位,并增加到随机码中,36位包含了0-9a-z*/ 		random += Integer.toString(count%36, 36); 		start = end; 	} 	/*返回随机码*/ 	return random; }

泡杯咖啡,清醒一下,随机码生成函数2应运而生,小学生(入门级程序员)都能看懂。经过测试,生成100万条长度4的随机码,重复率也在25%左右。

推荐方法:

/**  * 随机码生成  * @author Mo  *   * @param length  * @return  */ public static String random2(int length){ 	String random = ""; 	/*随机数函数*/ 	java.util.Random r=new java.util.Random(); 	for(int i = 0;i<length;i++){ 		/*生成36以内的随机数,不含36,并转化为36位*/ 		random += Integer.toString(r.nextInt(36), 36); 	} 	return random; }

事实证明,最复杂的方法并不是最好的方法,程序开发跟其他的事情一样,不要画蛇添足,时间浪费了,性能浪费了,还得不到好的结果。当然,多尝试是对的。

事后想想,既然是随机生成,又要控制长度,长度为4,又怎么会出现不重复的数字呢。当然,将长度调整到8的时候,重复率基本没有,这个没有也不能绝对,只是说概率降低了而已。

总结:要生成不重复的随机码,必经要经过数据验证,拿新生成的随机码去与历史生成数据对比,如果已存在,则舍弃重新生成。如果对长度没要求,可以直接采用UUID,UUID是国际通用的不重复的串,不过长度达到了36位之多。

以下提供一个自写随机码测试函数:

public static void main(String args []){ 	Set<String> set = new HashSet<String>(); 	int times = 1000000; 	for(int i = 0 ;i<times;i++){ 		String random = random1(8); 		set.add(random); 	} 	System.out.println("重复了:"+(times-set.size())+"次"); }

关于java的更多交流,请给我留言,简单的问题,也可以很复杂化,只有更深入的去尝试,才能更深刻的理解每一个细节问题。