java - 使用 StringBuilder 生成随机字符串会导致长度小于预定义长度的字符串

标签 java

我正在使用 for 循环和 StringBuilder 生成许多具有指定长度的随机字符串,但我得到的字符串比指定长度短。我的问题是,为什么有些字符串生成的长度正确,而有些则不然?

public class PasswordGen {

    public static void main(final String[] args) {
        final String[] chars = characters.split("");
        final List<String> characterList = Arrays.asList(chars);
        final Random rng = new SecureRandom();
        Collections.shuffle(characterList, rng);
        final int passwordsToGenerate = 16;
        final int length = 31;
        for (int i = 0; i < passwordsToGenerate; i++) {
            final StringBuilder builder = new StringBuilder();
            for (int j = 0; j < length; j++) {
                final int index = rng.nextInt(characterList.size());
                builder.append(characterList.get(index));
            }
            final String password = builder.toString();
            System.out.println(password);
            if (password.length() < 31) {
                System.out.println("^ is not 31 characters in length: " + password.length());
            }
        }

    }

    public static final String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}

输出:

LMUYN7bHKX13Rx1dwEkbHI8KjUONbDN
hnwMBD2LPHyuoYffGy7eC5STAg8heB
^ is not 31 characters in length: 30
EbburpyvZqc71mPadP8rYc6cJ8K9wl
^ is not 31 characters in length: 30
nLb58OzfnERsPm1SdR1nKBuOilhXzG
^ is not 31 characters in length: 30
c44M4Pk1kDIBMVqL0o5NybPA5t8zI3D
I3ttG7TvO8pKOp9yb5mGzJtnkTNVLH9
K1md1ORt2W3s8iR3RpMf2yNHjMrH8N
^ is not 31 characters in length: 30
G8daUMVLoMqpYqSrAUzSdI5IJCM7GSM
KMfaLvfCaudpRACpuOlA1gO3rqmhBs
^ is not 31 characters in length: 30
Y20V5RcKUiS8Ny9NpARmTMac29y8Z
^ is not 31 characters in length: 29
Rse101oxhOMXRdpchp4X3Uzm00Gzsc
^ is not 31 characters in length: 30
oQxaYE9qx1cEJP8KvTGdwo1IJhNH41O
y6E2WrKEAl2zWV6BCkH1JaWvz3aBxvs
QFautBHKlgDPlJhmge7n6Kf79G6mfu
^ is not 31 characters in length: 30
l2OBC9sFsZOfB481HXLsIiIwnmcOpdB
A4CTQj9Xc7grxtYYFzDRLelf3YQOTWV

我尝试在内部 for 循环中添加一个 Thread.sleep() block ,在获取下一个索引之前和之后,在将字符附加到构建器之前和之后,在设置密码变量,以及内部循环之前和之后,看看它是否与线程有关。结果没有明显差异。

我使用的是 Windows 7 Professional 64 位,并使用 JDK 7u67 和 8u11 进行了测试,32 位和 64 位的结果相同。

最佳答案

不要用空字符串分割字符,只需使用 getChars 方法。在不同版本的 java 中,按空字符串分割的行为并不相同。例如:Java split string on empty delimiter returns empty string at the beginning?

关于java - 使用 StringBuilder 生成随机字符串会导致长度小于预定义长度的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27223688/

相关文章:

java - Master 和 Slave 节点都必须进行哪些 Hadoop 配置?

java - JPMS/Jigsaw Java 11 Maven 应用程序中的 Keycloak-Admin-Client - 依赖问题

java - Jaxb 没有发现我的基类的正确儿子

java - 为什么我的背景图像没有显示在 FXML 中

java - 为什么我的漫射照明在 Java 中计算错误?

java - 在主节点 : binding to port 8040 java.net.BindException

java - 如何创建一个从其他 map 获取值然后将它们映射到其字段的 map ?

java - 如何停止 slider 上的无限循环

java - Gradle 构建在不同项目上总是失败

java - 在 Slick2D 上只显示图像的一半?