Solaris 中的随机数生成?

Solaris 中的随机数生成?

在 Solaris 中生成随机数的最佳方法是什么?

我似乎无法为此找到一个好的答案。大多数结果在我的环境中不起作用。有一个变量或命令 RAND 看起来很合乎逻辑,它会以类似于 $RANDOM 的方式工作,我在大多数搜索中都看到它,但它总是产生 0。

我找到了这个命令

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会生成适合加密使用的随机字节流。由于这些是任意字节,可能包括空字节,因此您不能将它们存储在 shell 变量中。您可以将$n字节存储在文件中

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

您可以od使用八进制或十六进制值将这些字节转换为可打印的表示形式。如果您发现输出“奇怪”,那么,也许您应该选择不同的od选项。

获取可打印表示的另一个选项是调用uuencode生成 Base64:

</dev/random dd ibs=1 count=$n | uuencode -m _ | sed -e '1d' -e '$d'

答案2

这是获取字节(以十六进制数字n表示)的三种方法: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)。

十六进制数字可以重定向到文件或存储在变量中:

 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 不可用,并假设十六进制数字位于$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*]"

尽管数字分布对于 0 来说非常有利,但对于以 10 为基数的情况应该可以很好地工作并且不会浪费任何东西。

对于 Solaris v<11,您将需要使用 ` 反引号而不是$(...)命令替换。

相关内容