複数の特殊文字を含むパスワードを生成するコマンドがあります。特殊文字を1つだけ生成するにはどうすればよいですか?
# Generate a random password
# $1 = number of characters; defaults to 32
# $2 = include special characters; 1 = yes, 0 = no; defaults to 1
function randpass() {
[ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
cat /dev/urandom | tr -cd "$CHAR" | head -c ${1:-32}
echo
}
答え1
これを行う方法はいくつかあります。
1. 「好きな」パスワードが得られるまで繰り返し続けます。
while true
do
word=$(tr -cd "[:graph:]" < /dev/urandom | head -c ${1:-32})
if [[ "$word" =~ [[:punct:]].*[[:punct:]] ]]
then
echo "$word has multiple special characters - reject."
continue
fi
if [[ "$word" =~ [[:punct:]] ]]
then
echo "$word has one special character - accept."
break
fi
echo "$word has no special characters - reject."
continue
done
警告:文字数が多い場合(たとえば、16文字以上)、時間がかかることがあります。
2. 句読点を読んだ後停止
n=${1:-32}
if [ "$2" == "0" ]
then
CHAR="[:alnum:]"
else
CHAR="[:graph:]"
fi
word=
for ((i=0; i<n; i++))
do
thischar=$(tr -cd "$CHAR" < /dev/urandom | head -c 1)
if ! [[ "$thischar" =~ [[:alnum:]] ]]
# Probably equivalent to if [[ "$thischar" =~ [[:punct:]] ]]
then
# Got one special character – don’t allow any more.
echo "$thischar is a special character."
CHAR="[:alnum:]"
fi
word="$word$thischar"
done
echo "$word"
これは最初の3つの特殊文字(例ab!defghijklmnopqrstuvwxyz123456
:)を取得します。非常に 頻繁に。また、この方法を使用すると、理論的に特殊文字が含まれていないパスワードを取得することも可能です。
答え2
[:alnum:]
まず32文字を作成し、オプションで特殊文字を挿入すると思いました。
function randpass() {
passwd=$( < /dev/urandom tr -cd "[:alnum:]" | head -c $1)
if [ "$2" == "0" ]; then
echo "$passwd"
else
spchar=$( < /dev/urandom tr -cd "[:punct:]" | head -c 1)
pos=$((RANDOM%$1))
echo "${passwd:0:pos}${spchar}${passwd:pos+1:$1}"
fi
}
私は[:punct:]
あなたが「特別」だと思うすべての文字が含まれていると仮定します。
構文は次のとおり$(( ))
です。シェル算術拡張0から31までの乱数(または任意の数字$1
)を生成します。
構文は次のとおり${var:offset:length}
です。シェルパラメータ拡張文字列から部分文字列を返します。
答え3
head
コマンドを次のように変更します-c 1
。
# Generate a random password
# $1 = number of characters; defaults to 32
# $2 = include special characters; 1 = yes, 0 = no; defaults to 1
function randpass() {
[ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
cat /dev/urandom | tr -cd "$CHAR" | head -c 1
echo
}