【问题标题】:Why does password input in Perl using Win32::Console require pressing Enter twice?为什么使用 Win32::Console 在 Perl 中输入密码需要按两次 Enter?
【发布时间】:2012-06-27 00:45:06
【问题描述】:

我对 Perl 还很陌生,很难掌握以下密码输入代码 sn-p 的行为:

use Win32::Console;

my $StdIn = new Win32::Console(STD_INPUT_HANDLE);
my $Password = "";

$StdIn->Mode(ENABLE_PROCESSED_INPUT());
local $| = 1;

print "Enter Password: ";
while (my $Data = $StdIn->InputChar(1)) {
    if ("\r" eq $Data ) {
        last;
    } 
    elsif ("\ch" eq $Data ) {
        if ( "" ne chop( $Password )) {
            print "\ch \ch";
        }
        next;
    }
    $Password .=$Data;
    print "*";
}

while (my $Data = $StdIn->InputChar(1)) {
    print "\nShow password? [y/n] ";
    if ("n" eq $Data) {
        last;
    }
    elsif ("y" eq $Data) {
        print "\nPassword: $Password\n";
        last;
    }
}

基本上发生的情况是脚本提示用户输入密码并按预期为每个字符输入显示*,但需要按两次Enter 才能接受输入。但是,如果我删除第二个 while 循环(或替换为 print $password 语句),输入只需要按一次 Enter

我还注意到,在第二个 while 循环中,提示用户输入 yn(无需按 Enter ) 如果用户输入“y”,则在显示密码之前重复行 Show password? [y/n]

对此行为的一些见解将不胜感激。

【问题讨论】:

  • @KenWhite 感谢您的编辑。这是一个令人尴尬的;-)

标签: windows perl windows-console


【解决方案1】:

第一个 Enter 让您退出第一个 while 循环。然后第二个while 循环在显示提示之前等待另一个字符。您应该在询问另一个字符之前显示提示(并且只显示一次)。

将事物分解为子例程有助于构建基本块。

use strict; use warnings;
use Win32::Console;

run();

sub run {
    my $StdIn = Win32::Console->new(STD_INPUT_HANDLE);
    $StdIn->Mode(ENABLE_PROCESSED_INPUT);

    my $Password = prompt_password($StdIn, "Enter Password: ", '*');

    if ( prompt_echo($StdIn, "\nShow password? [y/n] ") ) {
        print "\nPassword = $Password\n"
    }

    return;
}

sub prompt_password {
    my ($handle, $prompt, $mask) = @_;
    my ($Password);

    local $| = 1;
    print $prompt;

    $handle->Flush;

    while (my $Data = $handle->InputChar(1)) {
        last if "\r" eq $Data;

        if ("\ch" eq $Data ) {
            if ( "" ne chop( $Password )) {
                print "\ch \ch";
            }
            next;
        }

        $Password .= $Data;
        print $mask;
    }

    return $Password;
}

sub prompt_echo {
    my ($handle, $prompt) = @_;

    local $| = 1;
    print $prompt;
    $handle->Flush;

    while (my $Data = $handle->InputChar(1)) {
        return if "n" eq $Data;
        return 1 if "y" eq $Data;
    }

    return;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    相关资源
    最近更新 更多