-3

I have below code to encrypt the user password, when user enter the password an * symbol is displayed on the cmd prompt. In below code, an extra asterisks is always displaced when I run the command. Please let me know where I am doing wrong.

public static String readPassword(String prompt) {
    System.out.print(prompt);
    EraserThread et = new EraserThread(prompt);
    Thread mask = new Thread(et);
    mask.start();
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String password = "";
    try {
        password = in.readLine();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    et.stopMasking();
    return password;
}

class EraserThread implements Runnable {
    private boolean stop;

    public EraserThread(String prompt) {
        System.out.print(prompt);
    }

    @Override
    public void run() {
        stop = true;
        while (stop) {
            System.out.print("\010*");
            try {
                Thread.currentThread();
                Thread.sleep(1);
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

    public void stopMasking() {this.stop = false;}
}

i.e. an extra * is always displayed on the screen before entering the password.

Current Output :Enter text to be encrypted:*

expected output : Enter text to be encrypted:

Vineet
  • 877
  • 10
  • 26
geetha
  • 7
  • 5

1 Answers1

1

The main highlight of the erasure thread is this statement - System.out.print("\010*");.

\010 represents a backspace character. You could also use \b.

What the thread attempts to do is, after printing the prompt:

Enter password:

It will backspace/delete the last character, which in this example is : and then print a *. So the prompt will then look like this:

Enter password*

Every millisecond, it keeps doing the same. I.e. backspacing & placing a *. So, now the * that is printed, would get deleted and another * would be again printed in the same place. Which does nothing to final result - it's still the same. In fact it happens so fast that to us it looks static or like nothing is happening.

Once the person starts typing, e.g. a, it will look like this:

Enter password*a

Then after 1 millisecond the a gets deleted:

Enter password*

and a * is placed in its position:

Enter password**

This creates an illusion that what ever the user types is covered by *s. The actual string is obtained when we execute readLine(). If you want to see it happen in slow motion, you could increase the time to 1 second (1000ms).

I hope that explains to you why there's always an initial * in the prompt. One quick fix would be not to print anything at all. So the sysout would contain simple \010 or \b. This would be like the linux or sql terminals where when one inputs password, absolutely nothing appears on the terminal until an enter.

Vineet
  • 877
  • 10
  • 26