Скрыть ввод в командной строке
Я знаю, что интерфейсы командной строки, такие как Git, и другие могут скрывать ввод от пользователя (полезный для паролей). Есть ли способ программировать это на Java? Я беру пароль от пользователя, и я хотел бы, чтобы их ввод был "скрыт" на этой конкретной строке (но не на всех). Вот мой код для него (хотя я сомневаюсь, что это было бы полезно...)
try (Scanner input = new Scanner(System.in)) {
//I'm guessing it'd probably be some property you set on the scanner or System.in right here...
System.out.print("Please input the password for " + name + ": ");
password = input.nextLine();
}
Ответы
Ответ 1
Попробуйте java.io.Console.readPassword
. Однако вам придется работать хотя бы на Java 6.
/**
* Reads a password or passphrase from the console with echoing disabled
*
* @throws IOError
* If an I/O error occurs.
*
* @return A character array containing the password or passphrase read
* from the console, not including any line-termination characters,
* or <tt>null</tt> if an end of stream has been reached.
*/
public char[] readPassword() {
return readPassword("");
}
Остерегайтесь, однако, не работает с консолью Eclipse. Вам нужно будет запустить программу из подлинной команды console/shell/terminal/prompt, чтобы проверить ее.
Ответ 2
Да может быть сделано. Это называется маскировкой ввода в командной строке. Вы можете реализовать это легко.
Вы можете использовать отдельный поток, чтобы стереть эхо-символы по мере их ввода и заменять их звездочками. Это делается с использованием класса EraserThread, показанного ниже
import java.io.*;
class EraserThread implements Runnable {
private boolean stop;
/**
*@param The prompt displayed to the user
*/
public EraserThread(String prompt) {
System.out.print(prompt);
}
/**
* Begin masking...display asterisks (*)
*/
public void run () {
stop = true;
while (stop) {
System.out.print("\010*");
try {
Thread.currentThread().sleep(1);
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
/**
* Instruct the thread to stop masking
*/
public void stopMasking() {
this.stop = false;
}
}
Используя этот поток
public class PasswordField {
/**
*@param prompt The prompt to display to the user
*@return The password as entered by the user
*/
public static String readPassword (String 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();
}
// stop masking
et.stopMasking();
// return the password entered by the user
return password;
}
}
Эта ссылка подробно обсуждается.
Ответ 3
JLine 2 может представлять интерес. Помимо маскировки символов, он предоставит средства для завершения, редактирования и истории командной строки. Следовательно, это очень полезно для Java-инструмента на основе CLI.
Чтобы скрыть свой ввод:
String password = new jline.ConsoleReader().readLine(new Character('*'));
Ответ 4
Существует:
Console cons;
char[] passwd;
if ((cons = System.console()) != null &&
(passwd = cons.readPassword("[%s]", "Password:")) != null) {
...
java.util.Arrays.fill(passwd, ' ');
}
источник
но я не думаю, что это работает с IDE, например Eclipse, потому что программа выполняется как фоновый процесс, а не процесс верхнего уровня с консольным окном.
Другим подходом является использование JPasswordField
в swing с сопровождающим методом actionPerformed
:
public void actionPerformed(ActionEvent e) {
...
char [] p = pwdField.getPassword();
}
источник
Ответ 5
Класс Console имеет метод readPassword()
, который может решить вашу проблему.
Ответ 6
Если вы имеете дело с символьным массивом Java (например, с символами пароля, которые вы читаете с консоли), вы можете преобразовать его в строку JRuby со следующим кодом Ruby:
# GIST: "pw_from_console.rb" under "https://gist.github.com/drhuffman12"
jconsole = Java::java.lang.System.console()
password = jconsole.readPassword()
ruby_string = ''
password.to_a.each {|c| ruby_string << c.chr}
# .. do something with 'password' variable ..
puts "password_chars: #{password_chars.inspect}"
puts "password_string: #{password_string}"
См. также "fooobar.com/info/43468/..." и "fooobar.com/info/43455/..."