1.使用 SecureRandom.nextInt(…) 和 StringBuilder

一个简单的解决方案是从定义的 ASCII 范围中随机选择字符,并从中构造一个所需长度的字符串。要构造随机字母数字密码,ASCII 范围应由数字、大写和小写字符组成。

import java.security.SecureRandom;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    public static String generateRandomPassword(int len)
    {
        // ASCII 范围 – 字母数字 (0-9, a-z, A-Z)
        final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 
        SecureRandom random = new SecureRandom();
        StringBuilder sb = new StringBuilder();
 
        // 循环的每次迭代从给定的字符中随机选择一个字符
        // ASCII 范围并将其附加到 `StringBuilder` 实例
 
        for (int i = 0; i < len; i++)
        {
            int randomIndex = random.nextInt(chars.length());
            sb.append(chars.charAt(randomIndex));
        }
 
        return sb.toString();
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        System.out.println(generateRandomPassword(len));
    }
}

使用 Stream API 的等效版本

import java.security.SecureRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    public static String generateRandomPassword(int len)
    {
        // ASCII 范围 – 字母数字 (0-9, a-z, A-Z)
        final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 
        SecureRandom random = new SecureRandom();
 
        // 循环的每次迭代从给定的字符中随机选择一个字符
        // ASCII 范围并将其附加到 `StringBuilder` 实例
        return IntStream.range(0, len)
                .map(i -> random.nextInt(chars.length()))
                .mapToObj(randomIndex -> String.valueOf(chars.charAt(randomIndex)))
                .collect(Collectors.joining());
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        System.out.println(generateRandomPassword(len));
    }
}

2.使用 SecureRandom.ints(…) + 流

在 Java 8 及更高版本中, SecureRandom.ints(…) 方法可用于有效地返回指定范围内的伪随机值流。要将生成的伪随机值限制为字母数字值,请使用 filter(…) 流方法。要将过滤后的字母数字伪随机值限制为所需的长度,请调用 limit(…) 方法。最后,收集结果流中的值并构造一个字符串。

import java.security.SecureRandom;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    public static String generateRandomPassword(int len, int randNumOrigin, int randNumBound)
    {
        SecureRandom random = new SecureRandom();
        return random.ints(randNumOrigin, randNumBound + 1)
                .filter(i -> Character.isAlphabetic(i) || Character.isDigit(i))
                .limit(len)
                .collect(StringBuilder::new, StringBuilder::appendCodePoint,
                        StringBuilder::append)
                .toString();
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        int randNumOrigin = 48, randNumBound = 122;
 
        System.out.println(generateRandomPassword(len, randNumOrigin, randNumBound));
    }
}

上述解决方案生成所需长度的强随机字母数字密码。我们可以进一步简化代码以仅生成数字 (0-9) 密码,密码全部大写 (A-Z) 字符或全部小写 (a-z) 字符或属于某个 ASCII 范围内的任何其他字符。

例如,要生成所有小写字母的密码,请将范围设置为 97-122 (ASCII 值 ‘a’-‘z’).

import java.security.SecureRandom;
import java.util.stream.Collectors;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    public static String generateRandomPassword(int len, int randNumOrigin, int randNumBound)
    {
        SecureRandom random = new SecureRandom();
        return random.ints(len, randNumOrigin, randNumBound + 1)
                    .mapToObj(i -> String.valueOf((char)i))
                    .collect(Collectors.joining());
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        int randNumOrigin = 97, randNumBound = 122;
 
        System.out.println(generateRandomPassword(len, randNumOrigin, randNumBound));
    }
}

3. 使用 Apache Commons Text

一些第三方库提供了处理随机值的实用方法。如果您更喜欢 Apache Commons Text 库,则 RandomStringGenerator 类可以生成随机的 Unicode 字符串。它的实例是使用构建器类创建的。

使用 withinRange(…) 和 filteredBy(…)

import org.apache.commons.text.CharacterPredicates;
import org.apache.commons.text.RandomStringGenerator;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    public static String generateRandomPassword(int len, int randNumOrigin, int randNumBound)
    {
        RandomStringGenerator generator = new RandomStringGenerator.Builder()
                .withinRange(randNumOrigin, randNumBound)
                .filteredBy(CharacterPredicates.ASCII_ALPHA_NUMERALS)
                .build();
 
        return generator.generate(len);
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        int randNumOrigin = '0', randNumBound = 'z';
 
        System.out.println(generateRandomPassword(len, randNumOrigin, randNumBound));
    }
}

可以通过调用 Builder.usingRandom(…) 方法调整随机数生成器

public static String generateRandomPassword(int len, int randNumOrigin, int randNumBound)
{
    // 使用 Apache Commons RNG 实现随机性
    SecureRandom rng = new SecureRandom();
 
    RandomStringGenerator generator = new RandomStringGenerator.Builder()
            .withinRange(randNumOrigin, randNumBound)
            .filteredBy(CharacterPredicates.ASCII_ALPHA_NUMERALS)
            .usingRandom(rng::nextInt)
            .build();
 
    return generator.generate(len);
}

使用 selectFrom(…)

import org.apache.commons.text.RandomStringGenerator;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    // 使用 Apache Commons 文本 `RandomStringGenerator`
    public static String generateRandomPassword(int len)
    {
        // 提供字母数字 ASCII 范围 (0-9, a-z, A-Z)
        final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 
        RandomStringGenerator randomStringGenerator = new RandomStringGenerator.Builder()
                .selectFrom(chars.toCharArray())
                .build();
 
        return randomStringGenerator.generate(len);
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        System.out.println(generateRandomPassword(len));
    }
}

4. 使用 Apache Commons Lang

我们也可以使用 RandomStringUtils Apache Commons Lang 库的类。它提供了几种方法,例如 randomAlphabetic, randomAlphanumeric, randomNumeric等,以创建随机字符串。

例如,使用 randomAlphanumeric(…) 将创建一个指定长度的随机字母数字字符串。
```java
import org.apache.commons.lang3.RandomStringUtils;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    // 使用 Apache Commons Lang `RandomStringUtils`
    public static String generateRandomPassword(int len) {
        return RandomStringUtils.randomAlphanumeric(len);
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        System.out.println(generateRandomPassword(len));
    }
}

要从指定字符显式构造随机字符串,请调用 random(…) 方法。


import org.apache.commons.lang3.RandomStringUtils;
 
class Main
{
    // 生成特定长度的随机字母数字密码的方法
    // 使用 Apache Commons Lang `RandomStringUtils`
    public static String generateRandomPassword(int len)
    {
        final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        return RandomStringUtils.random(len, chars);
    }
 
    public static void main(String[] args)
    {
        int len = 10;
        System.out.println(generateRandomPassword(len));
    }
}

在 Java 中生成随机密码