2012-05-30 14 views
47

Wiem, że interfejsy wiersza komend, takie jak Git i inne, są w stanie ukryć dane wejściowe od użytkownika (przydatne w przypadku haseł). Czy istnieje sposób programowania tego w Java? Biorę hasło od użytkownika i chciałbym, aby ich dane wejściowe były "ukryte" w tym wierszu (ale nie we wszystkich). Tu jest mój kodu dla niego (choć wątpię, byłoby pomocne ...)Ukryj dane wejściowe w wierszu poleceń

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

Odpowiedz

75

Spróbuj java.io.Console.readPassword. Musisz jednak uruchamiać przynajmniej 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(""); 
    } 

Uważaj jednak, ten doesn't work z konsoli Eclipse. Będziesz musiał uruchomić program z konsoli true konsoli/powłoki/terminala/zachęty, aby móc go przetestować.

+21

+1 za poinformowanie mnie, że nie działa w konsoli Eclipse (chociaż używam Netbeans, najwyraźniej to też nie działa). – kentcdodds

+1

Przykładowe ćwiczenie: http://www.tutorialspoint.com/java/io/console_readpassword.htm – mavis

+3

Nie działa w większości środowisk IDE, ponieważ używają javaw. Zobacz http://stackoverflow.com/a/26473083/3696510 – muttonUp

3

Jest:

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

source

ale nie sądzę, to działa z IDE jak Eclipse, ponieważ program jest uruchamiany jako proces w tle, a nie najwyższym poziomie procesu z konsolą okno.

Innym podejściem jest użycie JPasswordField w rozkwicie z towarzyszącym actionPerformed metody:

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

source

11

Tak można zrobić. Nazywa się to maskowaniem wprowadzania poleceń w linii poleceń. Możesz to łatwo wdrożyć.

Możesz użyć oddzielnego wątku, aby usunąć wprowadzone znaki i zastąpić je gwiazdkami. Odbywa się to za pomocą klasy EraserThread pokazany poniżej

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

Przy użyciu tego wątku

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 omówić szczegóły.

+1

http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain -links-gdzie indziej-naprawdę-dobre-odpowiedzi –

+0

Zajmuję się tą odpowiedzią i lubię maskowanie hasłem. Proszę jednak o treść artykułu, który uznasz za przydatny, aby była to dobra odpowiedź. – kentcdodds

+1

+1 za zamieszczenie odpowiedniego kodu. – kentcdodds

7

JLine 2 mogą być interesujące. Oprócz maskowania znaków będzie zapewniał uzupełnianie wiersza poleceń, edytowanie i udostępnianie historii. W związku z tym jest bardzo przydatny w przypadku narzędzia Java opartego na interfejsie CLI.

Aby zamaskować swój wkład:

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

Klasa Console ma metodę readPassword() które mogłyby rozwiązać problem.

-2

Jeśli masz do czynienia z tablicy znaków (takich jak Java znaków hasła, które czytają z konsoli), można przekonwertować go na ciąg jruby z następującego kodu 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}" 

Zobacz również "https://stackoverflow.com/a/27628738/4390019" i "https://stackoverflow.com/a/27628756/4390019"

Powiązane problemy