webdevqa.jp.net

コマンドラインで入力を隠す

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();
}
57
kentcdodds

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コンソールでは 機能しない に注意してください。テストするには、trueconsole/Shell/terminal/Promptからプログラムを実行する必要があります。

85
adarshr

はい、できます。これは、コマンドライン入力マスキングと呼ばれます。これは簡単に実装できます。

別のスレッドを使用して、入力されたエコー文字を消去し、アスタリスクに置き換えます。これは、次に示す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;
   }
}

このリンク 詳細について話し合う。

13

JLine 2 は興味深いかもしれません。文字マスキングだけでなく、コマンドラインの補完、編集、および履歴機能も提供します。したがって、CLIベースのJavaツールに非常に役立ちます。

入力をマスクするには:

String password = new jline.ConsoleReader().readLine(new Character('*'));
8
Brian Agnew

がある :

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

ソース

しかし、これはEclipseのようなIDEでは動作しないと思います。これは、プログラムがコンソールウィンドウのトップレベルプロセスではなくバックグラウンドプロセスとして実行されるためです。

別のアプローチは、JPasswordFieldメソッドを伴うactionPerformedをswingで使用することです。

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

ソース

3
Dhruv Gairola

クラス Console には、問題を解決する可能性のあるメソッドreadPassword()があります。

0
rlinden