シェルで乱数を生成する7つの方法
I. 問題点
シェルは時々乱数を使う必要があるので、乱数の生成方法をまとめておきます。コンピュータが生成するのは、絶対乱数(理想的な乱数)ではなく、"擬似乱数"です。また、疑似乱数は大量に再現しても一意性を保つとは限りませんが、優れた疑似乱数生成アルゴリズムでは、非常に長い非反復の列が生成されます。
II. 乱数
1. 乱数を生成する7つの方法
(1) 内部システム変数($RANDOM)を介する場合
echo $RANDOM
0から32767までの整数を乱数で生成し、5以上の場合は10桁の固定整数を加算し、余りを計算する。
400000〜500000の乱数を発生させる。
#! /bin/bash
function rand(){
min=$1
max=$(($2-$min+1))
num=$(($RANDOM+1000000000)) # add a 10-bit number and remainder
echo $(($num%$max+$min))
}
rnd=$(rand 400000 500000)
echo $rnd
exit 0
(2) awk によるランダム関数
awk 'BEGIN{srand();print rand()*1000000}' # can add if judgment
(3) 乱数生成のためのopenssl rand
openssl randは、指定された長さのバイトのランダム文字を生成するために使用されます。-base64または-hexはランダムな文字列をbase64でエンコードするか、hexフォーマットで表示します。
openssl rand -base64 8 | md5sum | cut -c1-8 #a combination of eight letters and numbers, 3a61800e
openssl rand -base64 8 | cksum | cut -c1-8 #Eight digits, 10784736
(4) 時刻(日付)による乱数取得
date +%s%N #Generate 19-digit number, 1287764807051101270
date +%s%N | cut -c6-13 #Take eight digits, 21793709
date +%s%N | md5sum | head -c 8 # Combination of eight letters and numbers, 87022fda
1から50までの乱数を生成する。
#! /bin/bash
function rand(){
min=$1
max=$(($2-$min+1))
num=$(date +%s%N)
echo $(($num%$max+$min))
}
rnd=$(rand 1 50)
echo $rnd
exit 0
(5) システム内の固有データからの乱数生成(/dev/random、/dev/urandom)
/dev/randomには、現在システムが動作している環境に関するリアルタイムデータが格納されており、ある時点でのシステムの固有値データと見なすことができ、質の高い乱数を提供することができます。
/dev/urandomは、ブロッキングせずに読み出す乱数発生器で、高速で安全性の低い乱数発生器です。
cat /dev/urandom | head -n 10 | md5sum | head -c 10 #32f1e953ac
cat /dev/urandom | strings -n 8 | head -n 1 #Generate a full character random string, 08?WU$ZU
cat /dev/urandom | sed -e 's/[^a-zA-Z0-9]//g' | strings -n 8 | head -n 1 #Generate a random string of numbers plus letters, Ql2q9CXS, where strings -n sets the number of characters in the string and head -n sets the number of lines in the output.
head -200/dev/urandom| cksum |cut-d" " -f1 #urandom has a lot of data using cat will be slow, here use head to read 200 lines, cksum will read the contents of the file to generate a unique representation of the integer data, cut to " " split and then get the first field of the split data
(6) linuxのuuidコードを読み込む
UUIDコードの正式名称はUniversally Unique Identifier (UUID)で、UUIDのフォーマットは、8-4-4-4-12の32文字の形で、"-"接続番号で5セグメントに分けられた、32の16進数で構成されています。linuxのUUIDコードはカーネルからも提供されており、/proc/sys/kernel/random/uuidというファイルに入っています。
cat /proc/sys/kernel/random/uuid| cksum | cut -f1 -d" " # Get a different random integer, 1675034933
cat /proc/sys/kernel/random/uuid| md5sum | cut -c1-8 #Number plus letter random number, d69a7ebf
linux uuid を使って 100 から 500 までの乱数を生成しています。
#! /bin/bash
function rand(){
min=$1
max=$(($2-$min+1))
num=$(cat /proc/sys/kernel/random/uuid | cksum | awk -F ' ' '{print $1}')
echo $(($num%$max+$min))
}
rnd=$(rand 100 500)
echo $rnd
exit 0
(7) 要素プールからランダムに選択する
pool=(a b c d e f g h i j k l m n o p q r s t 1 2 3 4 5 6 7 8 9 10)
num=${#pool[*]}
result=${pool[$((RANDOM%num))]}
カスタムプールの要素を使って、数字や文字を含む特定の長さの文字列を生成するために使用します。
#! /bin/bash
length=8
i=1
seq=(0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
num_seq=${#seq[@]}
while [ "$i" -le "$length" ]
do
seqrand[$i]=${seq[$((RANDOM%num_seq))]}
let "i=i+1"
done
echo "The random string is:"
for j in ${seqrand[@]}
do
echo -n $j
done
echo
2. 乱数アプリケーション
(1) 乱数は、コンピュータシミュレーション、データ暗号化、オンラインゲームなど、インターネット上で広く利用されている。一部の掲示板やゲームにログインする際、システムが乱数や文字からなる画像を生成し、ユーザーが正しく入力する必要があるが、画像形式の文字は解読されにくいため、悪意ある攻撃を防ぐのに有効である。重要なテクニックは、乱数を生成し、その文字列をASP.NETなどのツールを使って画像形式にカプセル化し、認証画像として使用することである。
(2)オンラインゲームでも、サイコロを振ったり、カードを配ったりと、乱数がよく使われている。以下は、サイコロを1000回連続で振って、1点から6点までカウントした場合の回数です。
#! /bin/bash
#RANDOM=$$
PIPS=6
MAX=1000
throw=1
one=0
two=0
three=0
four=0
five=0
six=0
count()
{
case "$1" in
0) let "one=one+1";;
1) let "two=two+1";;
2) let "three=three+1";;
3) let "four=four+1";;
4) let "five=five+1";;
5) let "six=six+1";;
esac
}
while [ "$throw" -le "$MAX" ]
do
let "dice=RANDOM % $PIPS"
count $dice
let "throw=throw+1"
done
echo "The statistics results are as follows:"
echo "one=$one"
echo "two=$two"
echo "three=$three"
echo "four=$four"
echo "five=$five"
echo "six=$six"
RANDOMは、基本的に平均値の周りを浮遊する(つまり分散が小さい)乱数を生成します。
(3) ランダムなパスワードのシステムアカウント10個の一括作成
まず、ユーザーのパスワードを指定するスクリプトを見てみましょう。
#! /bin/bash
#Batch create 10 system accounts and set passwords, with the same account and password
for name in `seq -w 10`
do
#Non-interactive password entry
useradd linux$name && echo "linux$name" | passwd --stdin linux$name
done
linux-01からlinux-10まで、同じユーザー名とパスワードを持つ10人のユーザーがいる状態で、ランダムなユーザーパスワードを生成するスクリプトを見てみましょう。
#! /bin/bash
#Batch create 10 system accounts and set passwords
rm -f user.log
for name in `seq -w 10`
do
#Non-interactively enter a random password
password=`echo $RANDOM | md5sum | cut -c1-8`
#You can use password=`echo "date $RANDOM" | md5sum | cut -c3-11`
#You can also use password=`penssl rand -base64 8 | md5sum | cut -c1-8`
useradd linux$name && echo password | passwd --stdin linux$name
echo -e "user=linux$name \t passwd=$password" >> user.log #Save username password for review
done
この比較から、ランダムに生成されたパスワードの柔軟性と機密性がわかります。管理者はuser.logファイルを開き、先ほど作成した10人のユーザーに関する情報を記録することができます。
III. 概要
(1) 擬似乱数を生成するシェル関数$RANDOMは、より均等な分布を持つ擬似乱数を簡単に生成でき、ほとんどのアプリケーションのニーズを満たすことができる。
(2) 乱数生成の方法は他にもたくさんあり、拡張も可能なので、思考を拡張して最も近い方法を選択しましょう。
シェルで乱数を生成する7つの方法については、今回で終了です。シェルでの乱数についてもっと知りたい方は、スクリプトハウスの過去記事を検索するか、以下の記事を引き続きご覧ください。
関連
-
シェルスクリプトでnginxをインストールする詳細な手順 ソースコード
-
シェルバッチファイルの作成とリネームのサンプルコード
-
Bashスクリプトでaliasを導入する方法
-
シェル文字列傍受の実装方法(非常に詳細)
-
Rsyncはすべてのバックアップツールを殺す、あなたは手動で特定のディレクトリをブロックすることができますか?
-
Linuxでシェルスクリプトの先頭に固定書式を設定する方法
-
シェル文字列インターセプトエラー。不正な置換ソリューション
-
リナックスバウンスシェルの原理を解説
-
cdコマンドの使用を減らすためのautojumpコマンドのLinux実装
-
シェル $? 関数の戻り値、または直前のコマンドの終了ステータスを取得する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン