`
lazyman333
  • 浏览: 9487 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

巧用RandomStringUtils生成随机数

阅读更多

Java提供的随机数工具,或者第三方提供的随机数工具,都不能满足我的需求:产生指定位数且大于0的整数(可以做为ID使用)

        在使用commons-langRandomStringUtils类时,有一个方法引起了我的注意RandomStringUtils.randomNumeric(int count),该方法返回指定数目的随机数字串,如果把返回的数字串解析成数字,不就可以产生随机数了么~~~~

         按照上面的思路,做了一下封装,代码如下:

 

package org.lazyman.util
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.math.RandomUtils;
/**
 * @author yihuan
 * @version RandomNumberUtil.java 2010-1-14 上午11:39:20
 */
public class RandomNumberUtil {

	private static final int[] prefix = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

	/**
	 * 随机产生最大为18位的long型数据(long型数据的最大值是9223372036854775807,共有19位)
	 * 
	 * @param digit
	 *            用户指定随机数据的位数
	 */
	public static long randomLong(int digit) {
		if (digit >= 19 || digit <= 0)
			throw new IllegalArgumentException("digit should between 1 and 18(1<=digit<=18)");
		String s = RandomStringUtils.randomNumeric(digit - 1);
		return Long.parseLong(getPrefix() + s);
	}

	/**
	 * 随机产生在指定位数之间的long型数据,位数包括两边的值,minDigit<=maxDigit
	 * 
	 * @param minDigit
	 *            用户指定随机数据的最小位数 minDigit>=1
	 * @param maxDigit
	 *            用户指定随机数据的最大位数 maxDigit<=18
	 */
	public static long randomLong(int minDigit, int maxDigit)  {
		if (minDigit > maxDigit) {
			throw new IllegalArgumentException("minDigit > maxDigit");
		}
		if (minDigit <= 0 || maxDigit >= 19) {
			throw new IllegalArgumentException("minDigit <=0 || maxDigit>=19");
		}
		return randomLong(minDigit + getDigit(maxDigit - minDigit));
	}

	private static int getDigit(int max) {
		return RandomUtils.nextInt(max + 1);
	}

	/**
	 * 保证第一位不是零
	 * 
	 * @return
	 */
	private static String getPrefix() {
		return prefix[RandomUtils.nextInt(9)] + "";
	}
}

  

 

分享到:
评论
25 楼 sunnymoon 2010-01-28  
这样不保证唯一。
24 楼 lydawen 2010-01-26  
lazyman333 写道
Arden 写道
有这个东西的话不可以做数据库主键生成器了?

是的,我也是基于这个原因而做这个工具的


随机,如果你下次启动很有可能生成的随机数是一样的
23 楼 putonyuer 2010-01-26  
哈哈 楼上指出了真谛
22 楼 曾经de迷茫 2010-01-26  
lazyman333 写道
jd2bs 写道
扯 还DB 主键呢

randomNumeric的源码通读过了吗  做过严谨的测试吗

一眼看上去  这个函数的重复性不会比Random.nextInt小多少

离生成主键还远着呢,此处的用途不是为了产生db主键,生成的随机数是拿去访问db的,重复是允许的

随机数居然能和主键扯上关系?
--------------------------------
又长见识了。
21 楼 lazyman333 2010-01-26  
stupidmxx 写道
好吧。。。原来是这样的需求。what about this?
long base = (long)Math.pow(10, digit);
return rand.nextInt(base*9) + base; // 产生0到89999之间的符合平均分布的随机数,再加上10000,成为10000到999999之间的符合平均分布的随机数。

这样可行~~~
20 楼 lazyman333 2010-01-26  
putonyuer 写道

而randomNumeric  是更符合应用的

很赞同“更符合应用”这点,randomNumeric用起来方便
19 楼 lazyman333 2010-01-26  
jd2bs 写道
扯 还DB 主键呢

randomNumeric的源码通读过了吗  做过严谨的测试吗

一眼看上去  这个函数的重复性不会比Random.nextInt小多少

离生成主键还远着呢,此处的用途不是为了产生db主键,生成的随机数是拿去访问db的,重复是允许的
18 楼 lazyman333 2010-01-26  
gqf2008 写道
lazyman333 写道
Arden 写道
有这个东西的话不可以做数据库主键生成器了?

是的,我也是基于这个原因而做这个工具的

怎么保证不重复?

会有重复的,这只是产生随机数而已,不产生惟一主键
17 楼 putonyuer 2010-01-26  
jd2bs 写道
扯 还DB 主键呢

randomNumeric的源码通读过了吗  做过严谨的测试吗

一眼看上去  这个函数的重复性不会比Random.nextInt小多少



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++;
        }


这是randomNumeric 的实现代码, 它也是对random.nextInt 的封装
所以两者是相同的  ,或者  randomNumeric 更优 。 我没空继续读random.nextInt的实现。

而randomNumeric  是更符合应用的
16 楼 stupidmxx 2010-01-26  
jd2bs 写道
扯 还DB 主键呢

randomNumeric的源码通读过了吗  做过严谨的测试吗

一眼看上去  这个函数的重复性不会比Random.nextInt小多少


的确做主键是不可取的,毕竟这只是个随机数生成器而不是有contract约定的随机序列生成器。但是lz哪里有说要做db主键了吗?
15 楼 stupidmxx 2010-01-26  
lazyman333 写道
stupidmxx 写道
话说,

Random rand = new Random();
return rand.nextInt((long)Math.pow(10, digit));

这样不就行了么。。。

rand.nextInt(max)得到的结果是0到max-1的数,
而RandomNumberUtil.randLong(digit)产生的是指定位数的数,如果你传的参数是5,则返回结果是:10000到99999,同学仔细看看哦
IllegalArgumentException确实是RuntimeException的子类,谢谢同学提醒~~~ ,我已经改过来了

好吧。。。原来是这样的需求。what about this?
long base = (long)Math.pow(10, digit);
return rand.nextInt(base*9) + base; // 产生0到89999之间的符合平均分布的随机数,再加上10000,成为10000到999999之间的符合平均分布的随机数。
14 楼 bluethink 2010-01-26  
推荐使用JAVA 自带的UUID,
UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长.

GUID是一个128位长的数字,一般用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成GUID。从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义上)3240年不重复

import java.util.UUID;
...
String id = UUID.randomUUID().toString();

13 楼 DoubleEO 2010-01-26  
apache的工具包真是好多啊,这个没用过,谢谢分享~
12 楼 jd2bs 2010-01-26  
扯 还DB 主键呢

randomNumeric的源码通读过了吗  做过严谨的测试吗

一眼看上去  这个函数的重复性不会比Random.nextInt小多少
11 楼 gqf2008 2010-01-26  
lazyman333 写道
Arden 写道
有这个东西的话不可以做数据库主键生成器了?

是的,我也是基于这个原因而做这个工具的

怎么保证不重复?
10 楼 lazyman333 2010-01-25  
ialand 写道
不错,我以前也做过一个类似的东西,不过不是生成数字,而是一个固定长度的随机字符串,这个字符串随机取自a-z,0-9的字符,按照你这个需求,只需要从0-9里面随机取指定长度个数的元素组成一个固定的字符串,再把这个字符串转成数字即可,不知道有没有理解到你的需求。和你的不同是我没有用其它的第三方包,完全自己实现(因为不知道有这个东西),不过这种东西还是挺有意思的,呵呵

你理解得太到位了~~~ 其实commons-lang的RandomStringUtils.randomNumeric(int count)就相当于你实现的那个东西
9 楼 lazyman333 2010-01-25  
geweixin 写道

数据库主键生成器为什么不用UUID?

我们需要生成的随机数要在一定的范围,比如数据需要在10-12位之间,因为数据库里某种ID值是在这个范围内,程序把这种定制的值传给数据库,使得相应数据被加载进内存,以测数据库在大数据量下的性能情况
8 楼 ialand 2010-01-25  
不错,我以前也做过一个类似的东西,不过不是生成数字,而是一个固定长度的随机字符串,这个字符串随机取自a-z,0-9的字符,按照你这个需求,只需要从0-9里面随机取指定长度个数的元素组成一个固定的字符串,再把这个字符串转成数字即可,不知道有没有理解到你的需求。和你的不同是我没有用其它的第三方包,完全自己实现(因为不知道有这个东西),不过这种东西还是挺有意思的,呵呵
7 楼 geweixin 2010-01-25  
lazyman333 写道
Arden 写道
有这个东西的话不可以做数据库主键生成器了?

是的,我也是基于这个原因而做这个工具的

数据库主键生成器为什么不用UUID?
6 楼 lazyman333 2010-01-25  
Arden 写道
有这个东西的话不可以做数据库主键生成器了?

是的,我也是基于这个原因而做这个工具的

相关推荐

    配置文件详解:自定义属性、随机数、多环境配置等

    Spring Boot不直接提供生成随机数的功能,但你可以结合Java的`Random`类或者第三方库如`org.apache.commons.lang3.RandomStringUtils`来实现。例如,你可以在启动时生成一个随机数并保存为属性: ```properties ...

    java Xeger 根据正则表达式生成满足的随机数据

    Xeger是基于Java的org.apache.commons.text.RandomStringGenerator类和org.apache.commons.lang3.RandomStringUtils库的一个扩展,专为匹配正则表达式而设计。这个功能在测试、数据模拟和随机数据生成场景中尤其有用...

    根据正则生成测试数据

    我们可以使用`Pattern`和`Matcher`类来解析和匹配正则表达式,而`Random`类则可以生成随机数,结合这两者,我们就可以构建出满足正则要求的随机数据。 首先,我们需要一个函数来根据正则表达式生成单个随机字符串。...

    servlet生成验证码图片

    我们可以使用Java的`Random`类或者`SecureRandom`类生成随机数,然后将其转换为字符。考虑到可读性,可以限制字符集为大写字母、小写字母和数字。 2. **组合验证码字符串**:将生成的随机字符拼接成一个字符串,这...

    自动生成随机密码

    在这种情况下,可以使用`RandomStringUtils.randomAlphanumeric(int count)`或`RandomStringUtils.randomAlphabetic(int count)`结合`RandomStringUtils.randomAscii(int count)`,根据需求生成包含特定字符集的随机...

    java随机码生成程序

    首先,我们可以使用`java.util.Random`类来生成随机整数或浮点数。`Random`类是Java内置的随机数生成器,可以生成0到最大值(包括0但不包括最大值)之间的随机数。例如,要生成一个1到100之间的随机整数,可以这样做...

    随机生成验证码

    例如,生成一个4位的验证码,可以是`RandomStringUtils.random(4, true, true)`(使用Apache Commons Lang库)。 3. **扭曲和干扰**:为了增加自动化程序识别的难度,通常会对验证码图像进行扭曲、加噪或者添加干扰...

    java验证码生成类

    或者使用第三方库如Apache Commons Lang的`RandomStringUtils`,简化随机字符串的生成。 总的来说,Java验证码生成类的设计和实现涉及到图像处理、随机数生成以及会话管理等多个技术领域。通过理解并实践这些知识点...

    自动生成ID(32位)所用jar

    例如,可以使用`org.apache.commons.lang3.RandomStringUtils`类,它提供了生成随机字符串的方法。以下是如何利用这个类来生成32位的随机字符串ID: ```java import org.apache.commons.lang3.RandomStringUtils; ...

    java 生成32位UUID

    此外,还可以参考开源项目中的实现,例如Apache Commons Lang的`org.apache.commons.lang3.RandomStringUtils`类,它提供了生成固定长度随机字符串的方法。通过结合特定算法,可以使用这个工具类生成具有全局唯一性...

    数据生成器

    1. **随机数生成**:Java的`java.util.Random`类是生成随机数的基础。通过设置范围和类型(整数、浮点数),可以生成各种随机数据。例如,`nextInt()`用于生成整数,`nextDouble()`用于生成双精度浮点数。 2. **...

    commons-lang.zip

    使用`RandomStringUtils`可以很方便地在测试代码中生成模拟数据,或者在需要随机字符串的场景下快速实现功能。例如,在密码重置、生成唯一标识符或者填充数据库测试数据时,它都是非常有用的工具。 在实际项目中,...

    34丨 实战一(上):通过一段ID生成器代码,学习如何发现代码质量问题1

    可以优化为一次性生成一个8位长的随机字符串,例如使用`StringBuilder`和`RandomStringUtils.randomAlphanumeric()`方法。 4. **并发安全性**:如果这个ID生成器在多线程环境下使用,可能存在并发问题。由于`Random...

    验证码图片生成

    在实际的实现中,验证码生成系统会首先生成一个随机字符串,然后使用`RandomImage.java`中的方法将其转化为扭曲的图像。`UserwebRandomImage.java`会处理与用户交互的部分,如显示验证码图片,以及处理用户输入的...

    发送手机验证

    可以使用Java的Random类或第三方库如Apache Commons Lang的RandomStringUtils生成。 2. 存储验证码:生成的验证码需要临时存储,一般在服务器端的内存或数据库中,以便后续验证。同时,需要设置过期时间以确保安全性...

    javaWeb 生成验证码程序

    10. **第三方库**:在实际开发中,为提高效率,开发者可能会选择使用第三方库,如Apache Commons Codec的`RandomStringUtils`,或者开源验证码库如JCaptcha、EasyCAPTCHA等。 以上就是关于"JavaWeb生成验证码程序...

    验证码程序

    - **随机字符串生成**:利用`RandomStringUtils`类中的`randomAlphanumeric`方法生成包含字母和数字的随机字符串。 - **图像处理**:通过`BufferedImage`和`Graphics`对象绘制验证码图像,涉及颜色设置、字体样式和...

    springboot实现验证码校验demo

    在Spring Boot中,我们可以使用Java的`Random`类或者第三方库如Apache Commons Lang的`RandomStringUtils`来生成随机字符串。图像部分则可以通过Java的`BufferedImage`类和`Graphics2D`接口实现,将字符串绘制到图像...

    verificationcode.rar

    在Spring Boot中,我们可以使用第三方库如`Google's Guava`的`RandomStrings`类或者`Apache Commons Lang`的`RandomStringUtils`来生成随机字符串作为验证码。生成的验证码通常包含4到6个随机字符,可以是字母或数字...

    javaee超级验证码

    1. **验证码生成**:在服务器端,我们可以使用Java的`Random`类或第三方库(如Apache Commons Lang的`RandomStringUtils`)来生成随机字符串。这个字符串将作为验证码的值,同时可以通过图像库(如Java的`Java2D`或...

Global site tag (gtag.js) - Google Analytics