如何在特定范围内生成随机int值?

以下方法存在与整数溢出相关的错误:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.

当前回答

import java.util.Random;

public class RandomSSNTest {

    public static void main(String args[]) {
        generateDummySSNNumber();
    }


    //831-33-6049
    public static void generateDummySSNNumber() {
        Random random = new Random();

        int id1 = random.nextInt(1000);//3
        int id2 = random.nextInt(100);//2
        int id3 = random.nextInt(10000);//4

        System.out.print((id1+"-"+id2+"-"+id3));
    }

}

您也可以使用

import java.util.concurrent.ThreadLocalRandom;
Random random = ThreadLocalRandom.current();

然而,这个类在多线程环境中表现不佳。

其他回答

Java 17引入了RandomGenerator接口,它提供了一个int nextInt(int origin,int bound)方法来获取范围内的随机整数:

// Returns a random int between minimum (inclusive) & maximum (exclusive)
int randomInt = RandomGenerator.getDefault().nextInt(minimum, maximum);

除了用于Java17中添加的新的随机生成算法之外,该接口还添加到现有的随机生成类(random、SecureRandom、SplitableRandom和ThreadLocalRandom)中。因此,从Java 17开始,这些类具有以下有界nextInt方法:

new Random().nextInt(minimum, maximum);
new SecureRandom().nextInt(minimum, maximum);
new SplittableRandom().nextInt(minimum, maximum);
new ThreadLocalRandom().nextInt(minimum, maximum);

从Java17开始,这种方法是Random和SecureRandom的新方法。在Java17之前,ThreadLocalRandom和SplitableRandom已经有了这个方法,尽管它不是由共享接口指定的。

您可以按以下方式操作。

import java.util.Random;
public class RandomTestClass {

    public static void main(String[] args) {
        Random r = new Random();
        int max, min;
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter maximum value : ");
        max = scanner.nextInt();
        System.out.println("Enter minimum value : ");
        min = scanner.nextInt();
        int randomNum;
        randomNum = r.nextInt(max) + min;
        System.out.println("Random Number : " + randomNum);
    }

}

假设您希望范围在0-9之间,0是最小值,9是最大值。以下函数将打印0到9之间的任何内容。所有范围都一样。

public static void main(String[] args) {
    int b = randomNumberRange(0, 9);
    int d = randomNumberRange (100, 200);
    System.out.println("value of b is " + b);
    System.out.println("value of d is " + d);
}

public static int randomNumberRange(int min, int max) {
    int n = (max + 1 - min) + min;
    return (int) (Math.random() * n);
}

为了避免重复多次所说的内容,我为那些需要加密更强的伪随机数生成器的人展示了一种替代方法,方法是使用SecureRandom类,该类扩展了random类。从源代码中可以看到:

此类提供加密强随机数生成器(RNG)。密码强随机数最小符合使用FIPS中指定的统计随机数生成器测试140-2,加密模块的安全要求,第4.9.1节。此外,SecureRandom必须产生非确定性输出。因此,传递给SecureRandom对象的任何种子材料必须不可预测,并且所有SecureRandom输出序列必须如RFC 1750:随机性中所述,加密性强安全建议。调用者通过no参数获得SecureRandom实例构造函数或getInstance方法之一:SecureRandom随机=新的SecureRandum();许多SecureRandom实现采用伪随机数生成器的形式(PRNG),这意味着他们使用确定性算法来生成来自真实随机种子的伪随机序列。其他实施方式可以产生真正的随机数,而其他人可以使用组合这两种技术的组合。

要生成介于最小值和最大值之间的随机数,请执行以下操作:

public static int generate(SecureRandom secureRandom, int min, int max) {
        return min + secureRandom.nextInt((max - min) + 1);
}

对于给定的最小(含)和最大(不含)值:

return min + secureRandom.nextInt((max - min));

运行代码示例:

public class Main {

    public static int generate(SecureRandom secureRandom, int min, int max) {
        return min + secureRandom.nextInt((max - min) + 1);
    }

    public static void main(String[] arg) {
        SecureRandom random = new SecureRandom();
        System.out.println(generate(random, 0, 2 ));
    }
}

stackoverflow、baeldung、极客等来源提供了Random和SecureRandom类之间的比较。

从baeldung可以看到:

使用SecureRandom最常见的方法是生成int、long、,浮点、双精度或布尔值:int randomInt=secureRandom.nextInt();long randomLong=secureRandom.netLong();float randomFloat=secureRandom.netFloat();doublerandomDouble=secureRandom.nexDouble();boolean randomBoolean=secureRandom.nextBoolean();为了生成int值,我们可以传递一个上界作为参数:int randomInt=secureRandom.nextInt(上限);此外,我们可以为int、double和long生成一个值流:IntStream randomIntStream=secureRandom.ints();LongStream randomLongStream=secureRandom.long();DoubleStream randomDoubleStream=secureRandom.doubles();对于所有流,我们可以显式设置流大小:IntStream IntStream=secureRandom.ints(streamSize);

该类提供了几个其他选项(例如,选择基础随机数生成器),这些选项超出了本问题的范围。

Use:

minValue + rn.nextInt(maxValue - minValue + 1)