18

我有一个要求用户输入密码的 Perl 脚本。如何在用户键入时仅回显“*”来代替用户键入的字符?

我正在使用 Windows XP/Vista。

4

7 回答 7

24

过去我为此使用过IO::Prompt

use IO::Prompt;
my $password = prompt('Password:', -e => '*');
print "$password\n";
于 2009-04-02T13:55:37.960 回答
19

如果您不想使用任何软件包...仅适用于 UNIX

system('stty','-echo');
chop($password=<STDIN>);
system('stty','echo');
于 2010-02-10T09:44:25.707 回答
17

您可以使用 Term::ReadKey。这是一个非常简单的示例,对退格键和删除键进行了一些检测。我已经在 Mac OS X 10.5 上对其进行了测试,但根据ReadKey 手册,它应该可以在 Windows 下运行。手册指出在 Windows下使用非阻塞读取 ( ReadKey(-1)) 将失败。这就是为什么我使用基本上是 ReadKey(0) 的原因getc(更多关于 getc 在libc 手册中)。

#!/usr/bin/perl                                                                                                                                                                                                

use strict;                                                                                                                                                                                                    
use warnings;                                                                                                                                                                                                  
use Term::ReadKey;                                                                                                                                                                                             

my $key = 0;                                                                                                                                                                                                   
my $password = "";                                                                                                                                                                                             

print "\nPlease input your password: ";                                                                                                                                                                        

# Start reading the keys                                                                                                                                                                                       
ReadMode(4); #Disable the control keys                                                                                                                                                                         
while(ord($key = ReadKey(0)) != 10)                                                                                                                                                                            
# This will continue until the Enter key is pressed (decimal value of 10)                                                                                                                                      
{                                                                                                                                                                                                              
    # For all value of ord($key) see http://www.asciitable.com/                                                                                                                                                
    if(ord($key) == 127 || ord($key) == 8) {                                                                                                                                                                   
        # DEL/Backspace was pressed                                                                                                                                                                            
        #1. Remove the last char from the password                                                                                                                                                             
        chop($password);                                                                                                                                                                                       
        #2 move the cursor back by one, print a blank character, move the cursor back by one                                                                                                                   
        print "\b \b";                                                                                                                                                                                         
    } elsif(ord($key) < 32) {                                                                                                                                                                                  
        # Do nothing with these control characters                                                                                                                                                             
    } else {                                                                                                                                                                                                   
        $password = $password.$key;                                                                                                                                                                            
        print "*(".ord($key).")";                                                                                                                                                                              
    }                                                                                                                                                                                                          
}                                                                                                                                                                                                              
ReadMode(0); #Reset the terminal once we are done                                                                                                                                                              
print "\n\nYour super secret password is: $password\n";   
于 2009-03-31T14:29:46.163 回答
8

您应该查看Term::ReadKeyWin32::Console。您可以使用这些模块来读取单个按键并发出“*”或其他任何内容。

于 2009-03-31T14:10:10.420 回答
1

基于 Pierr-Luc 的程序,只是在反斜杠上添加了一些控制。有了这个,你不能一直按反斜杠:

sub passwordDisplay() {
    my $password = "";
    # Start reading the keys
    ReadMode(4); #Disable the control keys
    my $count = 0;
    while(ord($key = ReadKey(0)) != 10) {
            # This will continue until the Enter key is pressed (decimal value of 10)
            # For all value of ord($key) see http://www.asciitable.com/
            if(ord($key) == 127 || ord($key) == 8) {
                    # DEL/Backspace was pressed
                    if ($count > 0) {
                            $count--;
                            #1. Remove the last char from the password
                            chop($password);
                            #2 move the cursor back by one, print a blank character, move the cursor back by one
                            print "\b \b";
                    }
            }
            elsif(ord($key) >= 32) {
                    $count++;
                    $password = $password.$key;
                    print "*";
            }
    }
    ReadMode(0); #Reset the terminal once we are done
    return $password;
}
于 2012-08-30T07:49:00.243 回答
0

使用 Pierr-Luc 的程序

# Start reading the keys                                                                                                                                                                                       
ReadMode(4); #Disable the control keys                                                                                                                                                                         
while(ord($key = ReadKey(0)) != '13' )                                                                                                                                                                            
# This will continue until the Enter key is pressed (decimal value of 10)                                                                                                                                      
{                                                                                                                                                                                                              
    # For all value of ord($key) see http://www.asciitable.com/                                                                                                                                                
    if(ord($key) == 127 || ord($key) == 8 && (length($password) > 0)) {                                                                                                                                                                   
        # DEL/Backspace was pressed                                                                                                                                                                            
        #1. Remove the last char from the password                                                                                                                                                             
        chop($password);                                                                                                                                                                                       
        #2 move the cursor back by one, print a blank character, move the cursor back by one                                                                                                                   
        print "\b \b";                                                                                                                                                                                         
    } elsif(ord($key) > 32) {                                                                                                                                                                                  
        $password = $password.$key;                                                                                                                                                                            
        print "*";                                                                                                                                                                              
    }                                                                                                                                                                                                         
}                                                                                                                                                                                                              
ReadMode(0); #Reset the terminal once we are done
于 2019-02-07T14:49:40.287 回答
-4

您是否尝试过存储字符串(以便您的程序仍然可以读取它)并找出它的长度然后创建一个相同长度的字符串,但只使用'*'?

于 2009-03-31T13:59:54.767 回答