There is more articles on the online password mask input on Java, but it is not a comprehensive and detailed. Today, I saw this article on http://java.sun.com, and I plan to translate it. Because there is not enough experience, there may be in translation.
This article (referring to the original text) was previously published in September 2002. Under Java, it is very convenient to shield the user input password, but missing the I / O API, so it is not easy to implement Password Shadow like UNIX. This article uses the three cases of AWT / SWING / COMMAND LINE to introduce more detailed.
Password Masking In AWT -------------------------------- If you provide a graphical interface login dialog, you can use the AWT component library. The TEXTFIELD object defined in this object is as follows:
Java.lang.object | - java.awt.component | - java.awt.textcomponent | - java.awt.textfield
In this object, a method for setting up and maintaining a user input character is defined. These methods are defined in the form of: char getechochar (): Get user-defined text area return characters; boolean echocharisset () determines if defined Emnifact characters; Void Setechochar (Char C): Setting the text area back the display character as characters. The specific code is: textfield password = new textfield (8); password.setechochar ('*'); where 8 is the maximum number of characters entered, if 0, the password will not be blocked.
Password masking in swing --------------------------------- Using the JSWING component, you can use the JPasswordfield object, its inheritance structure To: java.lang.object | - java.awt.component | - java.awt.container | - javax.swing.jcomponent | - javax.swing.text.jtextComponent | - Javax .swing.jtextfield | - javax.swing.jpasswordfield
Specific code is: jpasswordfield password = new jpasswordfield (8); password.setechochar ('#');
Command-line Input Masking ---------------------------------- unlike AWT / SWING, there is no special in Java The API used to block the text on the command line. If you want to provide a Java application based on command line text, a method is to use Java Native Interface (JNI), but for a developer who is less familiar with C / C , or It is difficult to insist on using 100% pure Java developers.
Here is a solution for this problem, an earlier write about this problem, is like UNIX, with a separate thread to block (erase) Echizes characters. This article can now be seen at http://forum.java.sun.com/thread.jsp?forum=9&thread=490728. Simple solution ================ With a separate thread, erase the character in the character input, and replace it with an asterisk (*). code show as below:
//Raserthread.java
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 asseterisks (*) * / 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;}}
(Note: This method runs a lot of threads. If the computer takes a large load, the system will not guarantee the stability of thread operation.)
The PASSWORDFIELD class below uses the eraserthread class, used to replace the password characters entered by the user with (*).
//Passwordfield.java
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 InputStreamReader (STRING Password = ""
Try {password = in.readline ();} catch (ooexception ie) {oE.PrintStackTrace ();} // stop masking et.stopmasking (); // return the password entered by the user return password;}}. Java is an application for this method.
//Testapp.java
Class testapp {public static void main (string argv []) {string password = passwordfield.readpassword ("Enter Password:"); System.out.Println ("The password entered is:" password);}}
Let the code safer and reliable ======================= 1. Declare the private volatile boolean stop; Volatile keyword is used for the specified and process synchronization, in other words It is to say that the value of the variable is directly taken from the memory, and there is no copy in the stack. 2. To ensure stable operation on a heavy load, set the thread's priority.
//Maskingthread.java
Import java.io. *;
/ ** * this class attempts to Erase Characters echoed to the console. * /
Class Maskingthread Extends Thread {Private Volatile Boolean Stop; Private Char echochar = '*';
/ ** * @ param prompt the prompt displayed to the user * / public maskingthread (string prompt) {system.out.print (prompt);
/ ** * begin masking unsked to stop. * / Public void run () {
Int priority = thread.currentthread (). getPriority (); thread.currentthread (). setPriority (thread.max_priority);
Try {stop = true; while (stop) {system.out.print ("/ 010" echochar); try {// Attempt Masking At this Rate thread.currentthread (). Sleep (1);} catch (InterruptedException IEX ) {Thread.currentThread () interrupt ();. return;}}} finally {// restore the original priority Thread.currentThread () setPriority (priority);..}} / ** * Instruct the thread to stop masking * / Public void stopmasking () {this.stop = false;}}
Up the programs we see, use the String data type to store the sensitive information such as Password, the String object is not changeable, and after being used, it is not rewritable, so the following will replace it with a CHAR type .
Passwordfield.java
Import java.io. *; import java.util. *;
/ ** * this class prompt the user for a password and attempts to mask input with "*" * /
Public class passwordfield {
/ ** * @ Param INPUT stream to be used (e.g. system.in) * @ param prompt the prompt to display to the user. * @ Return the password as entered by the user. * /
public static final char [] getPassword (InputStream in, String prompt) throws IOException {MaskingThread maskingthread = new MaskingThread (prompt); Thread thread = new Thread (maskingthread); thread.start (); char [] lineBuffer; char [] buf ; Int I;
BUF = linebuffer = new char [128];
INT Room = Buf.length; int offset = 0; int C;
LOOP: While (True) {switch (c = in.read ()) {case -1: case '/ n': Break loop;
Case '/ r': int C2 = in.read (); if ((C2! = '/ n') && (C2! = -1)) {if (! (!) {in = new PushbackInputStream (in);} ((PushbackInputStream) .unread (c2);} else {Break loop;} default: if (--room <0) {buf = new char [offset 128]; room = buf.length - Offset - 1; System.ArrayCopy (Linebuffer, 0, BUF, 0, Offset); Arrays.Fill (Linebuffer, ''); linebuffer = buf;} buf [offset ] = (char) C; Break;}} Maskingthread .stopmasking (); if (offset == 0) {Return null;} char [] ret = new char [offset]; system.Arraycopy (buf, 0, ret, 0, offset); arrays.fill (buf, ' '); Return Ret;}}
Finally, a PASSWORDAPP Class is given by the following correction code.
// passwordapp.java
Import java.io. *;