Solarisで乱数を生成する最良の方法は何ですか?
これに対する良い答えが見つからないようです。ほとんどの結果は私の環境では機能しません。 $RANDOMと同様に動作する変数またはコマンドRANDを持つことは論理的なようです。ほとんどの検索では見たことがありますが、常にゼロが生成されます。
このコマンドが見つかりました
od -X -A n /dev/random | head -2
これはランダムに見えますが、戻り型は(私にとって)奇妙です。
140774 147722 131645 061031 125411 053337 011722 165106
066120 073123 040613 143651 040740 056675 061051 015211
現在使用されているもの:
-bash-3.2$ uname -a
SunOS XXXXXXXXX 5.10 Generic_150400-29 sun4v sparc SUNW,SPARC-Enterprise-T5120
答え1
$RANDOM
kshとbashで利用可能ですが/bin/sh
。値は 0 から 32768 までの任意の数値なので、暗号化には適していません。
読み取りは、/dev/random
暗号化の使用に適したランダムバイトストリームを生成します。これはヌルバイトを含むことができる任意のバイトなので、シェル変数に保存することはできません。$n
ファイルにバイトを保存できます
</dev/random dd ibs=1 count=$n >rnd
od
8進または16進値を使用して、これらのバイトを印刷可能な表現に変換できます。出力が「奇妙」な場合は、別のod
オプションを選択する必要があります。
印刷可能な表現を取得する別のオプションは、uuencode
Generate Base64を呼び出すことです。
</dev/random dd ibs=1 count=$n | uuencode -m _ | sed -e '1d' -e '$d'
答え2
以下は、バイト(16進数で表示n
)を取得する3つの方法です。2*n
#!/bin/bash
n=64
# Read n bytes from urandom (in hex).
xxd -l "$n" -p /dev/urandom | tr -d " \n" ; echo
od -vN "$n" -An -tx1 /dev/urandom | tr -d " \n" ; echo
hexdump -vn "$n" -e ' /1 "%02x"' /dev/urandom ; echo
urandomから読み込みます(必ずurandomを使用してください)。
16進数はファイルにリダイレクトするか、変数に保存できます。
a="$(xxd -l "$n" -p /dev/urandom)"
xxd を使用すると、次のように生のバイトを取得できます。
##警告、これはバイナリ値を生成します
echo "$a" | xxd -r -p # If the Hex digits are in a variable.
xxd -r -p "$rndfile" # If the Hex digits are in a file.
xxdが利用できず、16進数があると仮定すると、$a
次の
bashコードを使用できます。
#!/bin/bash
>"$rndfile" # erase the file
for (( i=0; i<${#a}/2; i++ )); do # do a loop over all byte values.
# convert 2 hex digits to the byte unsigned value:
printf '%b' $(printf '\\0%o' "0x${a:$i*2:2}") >> "$rndfile"
b="${b#??}" # chop out two hexadecimal digits.
done
あるいは、このsh互換コードを試すこともできます(bashで簡単に実行する必要があります)。はい、shと互換性があるはずです。問題が見つかったら報告してください。
ダッシュでのみテストされました(ただし他の一部では機能する必要があります)。
#!/bin/sh
i=$((${#a}/2)) # The (length of $a ) / 2 is the number of bytes.
b="$a" # use a temporal variable. It will be erased.
: >"$rndfile" # erase file contents
while [ $i != 0 ]; do
# Write one byte transformed to binary:
printf '%b' $(printf '\\0%o' "0x${b%"${b#??}"}") >> "$rndfile"
b="${b#??}" # chop out two hexadecimal digits.
i=$((i-1)) # One byte less to finish.
done
答え3
</dev/random \
dd bs="${num_len}" count=1 | LC_ALL=C \
tr -c 0-9 "$(printf '[%d*24]' 9 8 7 6 5 4 3 2 1)[0*]"
数値分布はゼロに非常に適していますが、十進法ではうまく機能し、何も無駄になりません。
$(...)
Solaris v < 11の場合は、コマンドの代わりに `バックティックを使用する必要があります。