2012-05-30 162 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