我有以下代码来加密用户密码,当用户输入密码时,cmd提示符上会显示*符号。在下面的代码中,当我运行命令时,总是会移动额外的星号。请让我知道我在哪里做错了。
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;}
}
即。在输入密码之前,屏幕上会始终显示额外的*
。
当前输出:Enter text to be encrypted:*
预期输出:Enter text to be encrypted:
答案 0 :(得分:0)
擦除主题的主要亮点是此声明 - System.out.print("\010*");
。
\010
表示退格符。您也可以使用\b
。
在打印提示后,线程尝试做的是:
Enter password:
它将退格/删除最后一个字符,在此示例中为:
,然后打印*
。所以提示符将如下所示:
Enter password*
每毫秒,它一直在做同样的事情。即退缩& amp;放置*
。因此,现在打印的*
将被删除,另一个*
将再次打印在同一位置。这对最终结果没有任何影响 - 它仍然是相同的。事实上它发生得如此之快,以至于它看起来很静止或者没有发生任何事情。
一旦此人开始输入,例如a
,它看起来像这样:
Enter password*a
然后在1毫秒后a
被删除:
Enter password*
并将*
置于其位置:
Enter password**
这会产生一种错觉,即*
s覆盖了用户类型。执行readLine()
时获取实际字符串。如果你想看到它以慢动作发生,你可以将时间增加到1秒(1000毫秒)。
我希望向您解释为什么提示中始终存在初始*
。一个快速解决方法是不打印任何东西。因此sysout
将包含简单的\010
或\b
。这就像linux或sql终端,当一个人输入密码时,终端上没有任何东西出现,直到输入。