当从扫描仪获取密码长度时,密码生成器抛出 IndexOutOfBoundsException

Password Generator throws IndexOutOfBoundsException when password length is taken from scanner

所以我为我的 Uni class 创建了一个随机密码生成器作为作业在应该生成我的密码的方法中。这是代码的更新版本,它实现了扫描仪作为用户从键盘输入 his/her 所需密码长度的选项。在以前的版本中,当密码长度被硬编码为一个设定数字时,它工作正常。 如果问题格式有任何错误或者代码看起来很丑什么的,我会事先道歉,因为我的编码水平在我目前的阶段是最底层的。

package com.company;
import java.util.*;

public class Main {

    static final String AllTheCharactersOnMyKeyBoard = "~!@#$%^&*()_+`1234567890-=QWERTYUIOP{}qwertyuiop[]ASDFGHJKL:|asdfghjkl;'|ZXCVBNM<>?zxcvbnm,./'";
    static int PasswordLength;
    static List<Character> ListOfCharsOnMyKBoard = convertsTheStringToCharacterList(AllTheCharactersOnMyKeyBoard);
    static char[] GeneratedCharacters= new char[PasswordLength];

    public static void main(String[] args) {
        Scanner PassLengthScanner=new Scanner(System.in);
        System.out.println("How many Symbols You wish the new password to contain?");
        PasswordLength= PassLengthScanner.nextInt();
        GeneratedPassword();
        System.out.println(ListOfCharsOnMyKBoard);
        System.out.println("\n\n\nYour Password is:");
        System.out.println(GeneratedCharacters);
    }
    public static List<Character> convertsTheStringToCharacterList(String AllTheCharactersOnMyKeyBoard){
        List<Character> MyKeyBoardCharacterList= new ArrayList<>();
        for (char CHARACTER : AllTheCharactersOnMyKeyBoard.toCharArray()){
            MyKeyBoardCharacterList.add(CHARACTER);
        }
        return MyKeyBoardCharacterList;
    }
    public static void GeneratedPassword(){
        Random TheGenerator= new Random();
        for (int i=0; i<PasswordLength; i++) {
            char RandomOne = ListOfCharsOnMyKBoard.get(TheGenerator.nextInt(ListOfCharsOnMyKBoard.size()));
            GeneratedCharacters[i]=(RandomOne);
        }
    }
}

堆栈跟踪是:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at com.company.Main.GeneratedPassword(Main.java:31)
    at com.company.Main.main(Main.java:15)

程序的第31行是这一行:

        GeneratedCharacters[i]=(RandomOne);
static int PasswordLength;

这声明了一个变量并将其初始化为 0。后半部分是Java的一个相当令人困惑的特征,我希望他们能避免它。

static char[] GeneratedCharacters= new char[PasswordLength];

这声明了一个数组变量并将其初始化为长度数组——等等,PasswordLength 的值是多少?对,0,所以一个长度为0的数组,里面没有元素的数组。

    PasswordLength= PassLengthScanner.nextInt();

这从键盘读取一个数字并将其存储在 PasswordLength 中。但是,它不会更改数组。该数组的长度仍然为 0。

        GeneratedCharacters[i]=(RandomOne);

这会尝试将值存储到数组元素中。第一次通过你的循环 i 是 0,所以它应该存储在索引 0 处的元素中,这通常应该没问题。只有因为你的数组是空的,它才会失败,并出现你看到的异常和堆栈跟踪(我希望你看到了堆栈跟踪)。

解决方案是在 main 方法中使用 new 分配数组,并且只有在将长度读入 PasswordLength.

之后

额外信息:不要将其用于真实密码。每个人都可以在 Stack Overflow 上看到您是如何生成它们的,并且 new Random() 给出了可预测的 运行dom 数字,当我们可以大致猜测您 运行 您的程序时。如果您想使用该程序获取真实密码,请像这样初始化 TheGenerator

    Random TheGenerator= SecureRandom.getInstance("SHA1PRNG");

简短解释:A SecureRandom 给出了不可预测的伪运行dom 数字,因此生成真实密码是安全的。