0

So I have made a random password Generator as homework for my Uni class, However i do have an issue with code breaking and exiting with "java.lang.IndexOutOfBoundsException : Invalid array range: 0 to 0" message once it gets to first itteration of loop in method that should generate my password. This is an updated version of code that implements scanner as option for user tu input his/her desired password lenght from keyboard. In previos version when password length was hardcoded as a set number, it worked allright. If there is anny mistake in question format or maybe the code looks ugly or whatever, I do apoligize beforehand as my coding skills are at the very bottom in my current stage.

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);
        }
    }
}

The stacktrace is:

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

Line 31 of the program is this line:

        GeneratedCharacters[i]=(RandomOne);
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 2
    When asking a question about an exception, **always** post the exact and complete stack trace of the exception. It tells you, and us, what and where the exception is. Anyway, when the line `static char[] GeneratedCharacters= new char[PasswordLength];`is executed, what is the value of `PasswordLength`. What do you conclude? – JB Nizet Jan 25 '20 at 11:47
  • 1
    Hi, welcome to SO. First of all, I suggest you to use the camel case convention, so variables and functions must start with a lower case letter, for example ```passLengthScanner```. – A. Wolf Jan 25 '20 at 11:48
  • 1
    Does this answer your question? [What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?](https://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it) – Progman Jan 25 '20 at 11:49
  • @JBNizet What is "Stack Trace of exception"? I coclude that PasswordLength = the integer input from keyboard when said line is executed, or am I missing something? – Thunder John Jan 25 '20 at 12:21
  • 1
    https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors – JB Nizet Jan 25 '20 at 12:21
  • Don’t use this for real passwords. Everyone can see here on Stack Overflow how you generated them, and `new Random()` gives predictable random numbers when we can guess approximately when you ran your program. It’s a fine exercise, though, you are learning from it. – Ole V.V. Jan 25 '20 at 12:44

1 Answers1

1
static int PasswordLength;

This declares a variable and initializes it to 0. The latter part is a quite confusing trait of Java, I wish they had avoided it.

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

This declares an array variable and initializes it to an array of length — wait, what is the value of PasswordLength? Right, 0, so an array of length 0, an array with no elements in it.

    PasswordLength= PassLengthScanner.nextInt();

This reads a number from the keyboard and stores it in PasswordLength. However, it doesn’t change the array. The array still has length 0.

        GeneratedCharacters[i]=(RandomOne);

This tries to store a value into an array element. The first time through your loop i is 0, so it should store into the element at index 0, which should most often be fine. Only since your array is empty, it fails with the exception and stack trace that you saw (I hope you saw the stacktrace).

The solution is to allocate the array with new inside the main method and only after you have read the length into PasswordLength.

Bonus info: Don’t use this for real passwords. Everyone can see here on Stack Overflow how you generated them, and new Random() gives predictable random numbers when we can guess approximately when you ran your program. If you want to use the program for real passwords, initialize TheGenerator like this:

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

Short version of explanation: A SecureRandom gives unpredictable pseudorandom numbers, so is safe for generating real passwords.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Thank You. Well explained. I did Your changes and now everything works fine. As a new student this quite confuses me (the fact that gave value to the element amount in array with scanner, yet java did not understand me). – Thunder John Jan 25 '20 at 13:22