ユーザーにパスワードの入力を要求する Perl スクリプトがあります。ユーザーが入力した文字の代わりに「*」のみをエコーするにはどうすればよいですか?
Windows XP/Vista を使用しています。
過去に、これにはIO::Promptを使用しました。
use IO::Prompt;
my $password = prompt('Password:', -e => '*');
print "$password\n";
パッケージを使用したくない場合... UNIXのみ
system('stty','-echo');
chop($password=<STDIN>);
system('stty','echo');
Term::ReadKey で遊ぶことができます。これは、バックスペースと削除キーを検出する非常に単純な例です。Mac OS X 10.5 でテストしましたが、ReadKey のマニュアルによると、Windows でも動作するはずです。マニュアルによると、Windows では非ブロッキング読み取り ( ReadKey(-1)
) を使用すると失敗します。そのため、基本的に ReadKey(0) を使用しています ( libc マニュアルgetc
の getc の詳細)。
#!/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";
Term::ReadKeyまたはWin32::Consoleのいずれかを確認する必要があります。これらのモジュールを使用して、単一のキーストロークを読み取り、「*」などを発行できます。
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;
}
文字列を保存して (プログラムが読み取れるように)、その長さを調べてから、同じ長さの文字列を作成しましたが、「*」のみを使用しましたか?