如何在特定范围内生成随机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`.

当前回答

为了避免重复多次所说的内容,我为那些需要加密更强的伪随机数生成器的人展示了一种替代方法,方法是使用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);

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

其他回答

使用Java 8 Streams,

传递初始容量-多少个数字将randomBound从x传递到randomBoud是否为已排序传递true/false传递新的Random()对象

 

public static List<Integer> generateNumbers(int initialCapacity, int randomBound, Boolean sorted, Random random) {

    List<Integer> numbers = random.ints(initialCapacity, 1, randomBound).boxed().collect(Collectors.toList());

    if (sorted)
        numbers.sort(null);

    return numbers;
}

在本例中,它从1-Randombound生成数字。

这里有一个有用的类,可以在包含/排除边界的任意组合范围内生成随机整数:

import java.util.Random;

public class RandomRange extends Random {
    public int nextIncInc(int min, int max) {
        return nextInt(max - min + 1) + min;
    }

    public int nextExcInc(int min, int max) {
        return nextInt(max - min) + 1 + min;
    }

    public int nextExcExc(int min, int max) {
        return nextInt(max - min - 1) + 1 + min;
    }

    public int nextIncExc(int min, int max) {
        return nextInt(max - min) + min;
    }
}

您可以编辑第二个代码示例以:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;

我认为这段代码会奏效。请尝试一下:

import java.util.Random;
public final class RandomNumber {

    public static final void main(String... aArgs) {
        log("Generating 10 random integers in range 1..10.");
        int START = 1;
        int END = 10;
        Random randomGenerator = new Random();
        for (int idx=1; idx<=10; ++idx) {

            // int randomInt=randomGenerator.nextInt(100);
            // log("Generated : " + randomInt);
            showRandomInteger(START,END,randomGenerator);
        }
        log("Done");
    }

    private static void log(String aMessage) {
        System.out.println(aMessage);
    }

    private static void showRandomInteger(int aStart, int aEnd, Random aRandom) {
        if (aStart > aEnd) {
            throw new IllegalArgumentException("Start cannot exceed End.");
        }
        long range = (long)aEnd - (long)aStart + 1;
        long fraction = (long) (range * aRandom.nextDouble());
        int randomNumber = (int) (fraction + aStart);
        log("Generated" + randomNumber);
    }
}

让我们举个例子。

假设我希望生成5-10之间的数字:

int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);

让我们了解这一点。。。

用最高值初始化max,用最低值初始化min。现在,我们需要确定可以获得多少可能的值。在本例中,应为:5, 6, 7, 8, 9, 10所以,这个计数应该是max-min+1。即10-5+1=6随机数将生成0-5之间的数字。即0、1、2、3、4、5将最小值添加到随机数将产生:5, 6, 7, 8, 9, 10 因此,我们获得了所需的范围。