私は乱数を生成するプログラムを作成していますが、乱数を生成する前にどのくらいの組み合わせがあるかを表示したいと思います。これを行うと、次のような結果が得られます。
64k@conroe$ bash random A-Za-z0-9 3
238328
possible combinations
CG1
私は「可能な組み合わせ」が「238328」と同じ行にあることを望みます。
238328 possible combinations
その部分のコードは次のとおりです。
if [ $1 == 'A-Z' ] || [ $1 == 'a-z' ]
then
echo "26^$2" | bc
elif [ $1 == 'A-Za-z' ] || [ $1 == 'a-zA-Z' ]
then
echo "52^$2" | bc
elif [ $1 == 'A-Z0-9' ] || [ $1 == 'a-z0-9' ]
then
echo "36^$2" | bc
elif [ $1 == 'A-Za-z0-9' ] ||[ $1 == 'a-zA-Z0-9' ]
then
echo "62^$2" | bc
else
echo "${#$1}^$2" | bc
fi
echo "possible combinations"
この時間を短縮する方法がある場合は、喜んで提案を受けたいと思います。私は初めてbashスクリプトに触れました。
echo | bc
また、カンマ区切りの数字を出力する方法はありますか?一部の数字は非常に大きくなる可能性があります。つまり、random A-Za-z0-9 10
可能な組み合わせの数はです839299365868340224
。表示できるようにカンマで区切りたいです839,299,365,868,340,224
。完全なコード:
if [ $1 == 'A-Z' ] || [ $1 == 'a-z' ]
then
echo "26^$2" | bc
elif [ $1 == 'A-Za-z' ] || [ $1 == 'a-zA-Z' ]
then
echo "52^$2" | bc
elif [ $1 == 'A-Z0-9' ] || [ $1 == 'a-z0-9' ]
then
echo "36^$2" | bc
elif [ $1 == 'A-Za-z0-9' ] ||[ $1 == 'a-zA-Z0-9' ]
then
echo "62^$2" | bc
else
echo "${#$1}^$2" | bc
fi
echo "possible combinations"
if [ $# == 2 ]
then
< /dev/urandom env LC_CTYPE=C tr -dc $1 | head -c $2 | while read -n 1 x
do
printf "\e[1;36m$x"
sleep 0.03
done
echo -e '\033[0m'
exit 0
exit 1
elif [ $# == 3 ]
then
for (( c=1; c<=$3; c++ ))
do {
< /dev/urandom env LC_CTYPE=C tr -dc $1 | head -c $2 | while read -n 1 x
do
printf "\e[0;33m$x"
sleep 0.03
done
echo -e '\033[0m'
}
done
exit 1
fi
答え1
他に何もなければ、case
文が必要です。
random(){
printf "%d^${2##*[!0-9]*}\n" "$(($(
export LC_ALL=C; a=$1
while x=${a%"${a#?}"} s=
case $a in
([a-z]-["$x"-z]*|[A-Z]-["$x"-Z]*)
a=${a#??} s=?
printf '(%d-%d+1)+' "'$a" "'$x";;
([0-9]-["$x"-9]*)
x=${a%"${a#???}"} a=${a#"$x"}
printf "$((-($x)+1))+";;
(?-*) a=${a#??}
echo 2+;;
(?*) x=${a%%[A-Za-z0-9]-*}
a=${a#"$x"}
echo "${#x}+";;
(*) ! echo 0 ;;esac
do a=${a#$s} ; done
)))" | bc| sed 's/$/ possibilities./
/^1 /s/....$/y./'
}
まあ、謝罪しなければなりません。私が思っていたcharクラスが文字通りのパラメータ文字列だと思いました。今私はあなたが言うことを理解しています。ちょうど働くようになりました - 実際に動作します。する違いを計算するので、あらゆる種類の文字を処理できます。
{ random A 1 #1 char and 1
random AB 1 #2 chars and 1
random a-Z 1 #3 chars because the range is invalid and 1
random aa-c 1 #4 chars: aabc and 1
random a-c 2 #3 chars: abc and 2
random aa-z 3) #27 chars:aa-z and 3
}
出力
1 possibility.
2 possibilities.
3 possibilities.
4 possibilities.
9 possibilities.
19683 possibilities.
最初にすべきことは、printf
2番目のパラメータを試すことです。${2##*[!0-9]*}
数値以外の文字が含まれている場合は、パラメータ拡張が行われ、nullとしてレンダリングされます。%d
igit値の算術拡張が先行し、完全な実行ループが発生します。この算術拡張は次のとおりです。進行中。実際、関数全体はprintf
現在のシェルの観点から見た説明にすぎません。
しかし、$((
数学拡張では、))
これは$(
命令の置き換え)
に過ぎず、それ以上ではありません。我々は何も提供しません。ただそれだけです$(($()))
。
コマンド置換のサブシェルを除外すると、ループを実行して出力を収集します。私たちの出力は最終的に実行可能な算術式にまとめられました。
$a
ループでは、常に各ループの先頭に最初の文字を置きます$x
。次に、$a
いくつかのパターンに基づいて現在の値のヘッダーを確認しますcase
。そのうちの最初のものは次のとおりです。
([a-z]-["$x"-z]*|[A-Z]-["$x"-Z]*)
$a
ここでは、2回保存した最初の文字を使用します$x
。まず、私たちのモデルを比較する議論です。しかし、2番目に、これは3番目の$a
文字のリミッタです。これは、3番目の文字がアルファベットの範囲内に収まるだけでなく、1$a
番目の文字以上であることを保証します。無効な範囲なので、z-a
テストに使用した場合は一致しません。$x
このパターンが一致すると、ヘッダーから2つの文字を削除して、各合計のASCII数値を印刷します$x
。$a
$a
このように:
printf '(%d-%d+1)+' "'$x" "'$a"
...これは最終算術で括弧サブ式になり、範囲間の距離を計算します。
数字にも同じことを行います。
([0-9]-["$x"-9]*)
$a
この場合も頭を切る。数字の数学は少し異なります。負の数を取得します。$a
の最初の3文字はに保存されます$x
。x=4-9
だから我々は以下を印刷します:
printf "$((-($x)+1))+"
担当者の場合$a
そうだ最初の2つのテストでまだ失敗する範囲と同様に、(?-*)
パターンと一致し、上位2文字を削除しecho 2+
て再度繰り返します。
パターンまで設定すると、可能な範囲で最初の項目が一致するまで(?*)
最初から$a
すべてが削除されます$a
。成功した場合はループを繰り返し繰り返し、差分を分割しますが、残りの部分に可能な範囲一致がない場合は、基本的にここですべての権限とエコーを$a
消費するため、ループを終了します。$a
${#a}+
まあ、私たちはあきらめません。しかし、$a
- ループの上部が空の状態に戻されるまで、ループは終了しません。これが発生した場合は、出力! echo 0
に書き込まれた最後の文字列を実行します。
したがって、現在のシェルに戻って数学拡張のすべての内容をprintと評価すると、出力"$((subshell_math))^$2"
はbc
パイプにリンクされ、出力にsed
文字列が追加されます。possibles.
これがうまくいく方法です。
答え2
バックティックを使用して出力を保存し、printfを使用してフォーマットすることができます。
if [ $1 == 'A-Z' ] || [ $1 == 'a-z' ]
then
combinations=`echo "26^$2" | bc`
elif [ $1 == 'A-Za-z' ] || [ $1 == 'a-zA-Z' ]
combinations=`echo "52^$2" | bc`
# ... and so on ...
fi
printf "%'.0f possible combinations\n" $combinations
コードを整理するという点で、後でパラメータをどのように使用するのかわからないのは少し難しいですが、変更したいのは、すべての可能な置換を見つけるのではなく、予想される部分を一度に確認することです。
#!/bin/bash
chars='0'
if [[ $1 == *"0-9"* ]]; then
chars="$chars+10"
fi
if [[ $1 == *"a-z"* ]]; then
chars="$chars+26"
fi
if [[ $1 == *"A-Z"* ]]; then
chars="$chars+26"
fi
combinations=`echo "($chars)^$2" | bc`
printf "%'.0f possible combinations\n" $combinations