2012-05-30 147 views
47

我知道像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(); 
} 

回答

75

尝试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(""); 
    } 

要小心的是,这doesn't work与Eclipse控制台。您必须从true console/shell/terminal /提示符运行该程序才能够对其进行测试。

+21

+1让我知道它在Eclipse控制台中不起作用(尽管我使用Netbeans,但显然它不起作用)。 – kentcdodds

+1

示例练习:http://www.tutorialspoint.com/java/io/console_readpassword.htm – mavis

+3

由于他们使用javaw,在大多数IDE中不起作用。请参阅http://stackoverflow.com/a/26473083/3696510 – muttonUp

3

有:

Console cons; 
char[] passwd; 
if ((cons = System.console()) != null && 
    (passwd = cons.readPassword("[%s]", "Password:")) != null) { 
    ... 
    java.util.Arrays.fill(passwd, ' '); 
} 

source

,但我不认为这有工作像Eclipse的IDE,因为程序运行的后台进程,而不是一个控制台顶级工艺窗口。

另一种方法是在摇摆并结合actionPerformed方法使用JPasswordField

public void actionPerformed(ActionEvent e) { 
    ... 
    char [] p = pwdField.getPassword(); 
} 

source

11

是可以做到的。这称为命令行输入掩码。您可以轻松实现。

您可以使用单独的线程擦除正在输入的回显字符,并用星号替换它们。这是使用下面

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

所示的EraserThread类使用此线程

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

This Link详细讨论完成。

+1

http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain -links-elsewhere-really-good-answers –

+0

我正在研究这个答案,我喜欢密码掩盖。但是请包括您认为有用的文章的内容,这是一个很好的答案。 – kentcdodds

+1

用于发布相关代码。 – kentcdodds

7

JLine 2可能是感兴趣的。除了字符遮罩之外,它还提供命令行完成,编辑和历史记录功能。因此它对于基于CLI的Java工具非常有用。

为了掩盖你输入:

String password = new jline.ConsoleReader().readLine(new Character('*')); 
0

Console有一个方法readPassword()可能解决您的问题。

-2

如果你正在处理一个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}" 

参见“https://stackoverflow.com/a/27628738/4390019”和“https://stackoverflow.com/a/27628756/4390019