golang--隱藏命令行用戶密碼

效果

在這裏插入圖片描述

github.com/howeyc/gopass

方法

GetPasswd

// GetPasswd returns the password read from the terminal without echoing input.
// The returned byte array does not include end-of-line characters.
// 返回從終端讀取的密碼,不在命令行輸出
func GetPasswd() ([]byte, error) {
	return getPasswd("", false, os.Stdin, os.Stdout)
}

GetPasswdMasked

// GetPasswdMasked returns the password read from the terminal, echoing asterisks.
// The returned byte array does not include end-of-line characters.
//返回從終端讀取的密碼,返回星號。
func GetPasswdMasked() ([]byte, error) {
	return getPasswd("", true, os.Stdin, os.Stdout)
}

GetPasswdPrompt

// GetPasswdPrompt prompts the user and returns the password read from the terminal.
// If mask is true, then asterisks are echoed.
// The returned byte array does not include end-of-line characters.
//提示用戶並返回從終端讀取的密碼。prompt用於提示用戶,mask-true表示返回星星,false不顯示。
func GetPasswdPrompt(prompt string, mask bool, r FdReader, w io.Writer) ([]byte, error) {
	return getPasswd(prompt, mask, r, w)
}

getPasswd

// getPasswd returns the input read from terminal.
// If prompt is not empty, it will be output as a prompt to the user
// If masked is true, typing will be matched by asterisks on the screen.
// Otherwise, typing will echo nothing.
func getPasswd(prompt string, masked bool, r FdReader, w io.Writer) ([]byte, error) {
	var err error
	var pass, bs, mask []byte
	if masked {
	    //\b \b表示退格
		bs = []byte("\b \b")
		mask = []byte("*")
	}

	//如果是命令行,需要充值命令行位置
	if isTerminal(r.Fd()) {
		if oldState, err := makeRaw(r.Fd()); err != nil {
			return pass, err
		} else {
			defer func() {
				restore(r.Fd(), oldState)
				fmt.Fprintln(w)
			}()
		}
	}

    //是否有提示
	if prompt != "" {
		fmt.Fprint(w, prompt)
	}

	// Track total bytes read, not just bytes in the password.  This ensures any
	// errors that might flood the console with nil or -1 bytes infinitely are
	// capped.
	var counter int
	for counter = 0; counter <= maxLength; counter++ {
		if v, e := getch(r); e != nil {
			err = e
			break
		} else if v == 127 || v == 8 {//127 del 8 退格
			if l := len(pass); l > 0 {
				pass = pass[:l-1]
				fmt.Fprint(w, string(bs))
			}
		} else if v == 13 || v == 10 {//13回車 10換行
			break
		} else if v == 3 {//正文結束
			err = ErrInterrupted
			break
		} else if v != 0 {//其他字符
			pass = append(pass, v)
			fmt.Fprint(w, string(mask))
		}
	}

	if counter > maxLength {
		err = ErrMaxLengthExceeded
	}

	return pass, err
}

Test code

	s1,_ := gp.GetPasswdMasked()
	fmt.Println(string(s1))
	s2,_ := gp.GetPasswd()
	fmt.Println(string(s2))
	s3,_ := gp.GetPasswdPrompt("請輸入密碼",true,os.Stdin,os.Stdout)
	fmt.Println(string(s3))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章