ソラリスで乱数を生成する?

ソラリスで乱数を生成する?

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

$RANDOMkshとbashで利用可能ですが/bin/sh。値は 0 から 32768 までの任意の数値なので、暗号化には適していません。

読み取りは、/dev/random暗号化の使用に適したランダムバイトストリームを生成します。これはヌルバイトを含むことができる任意のバイトなので、シェル変数に保存することはできません。$nファイルにバイトを保存できます

</dev/random dd ibs=1 count=$n >rnd

od8進または16進値を使用して、これらのバイトを印刷可能な表現に変換できます。出力が「奇妙」な場合は、別のodオプションを選択する必要があります。

印刷可能な表現を取得する別のオプションは、uuencodeGenerate 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の場合は、コマンドの代わりに `バックティックを使用する必要があります。

関連情報