如何使用 AShell(受限 bash)生成随机数?我在没有 od
或 $RANDOM
的设备上使用 BusyBox 二进制文件。我的设备有 /dev/urandom
和 /dev/random
。
最佳答案
$RANDOM
和 od
是 BusyBox 中的可选功能,鉴于您的问题,我假设它们不包含在您的二进制文件中。您在评论中提到 /dev/urandom
存在,这很好,这意味着您需要做的是以可用形式从中检索字节,而不是实现一个更困难的问题随机数发生器。请注意,您应该使用 /dev/urandom
而不是 /dev/random
,请参阅 Is a rand from /dev/urandom secure for a login key? .
如果你有 tr
或 sed
,你可以从 /dev/urandom
读取字节并丢弃任何不需要的字节特点。您还需要一种从流中提取固定数量字节的方法:head -c
(需要启用 FEATURE_FANCY_HEAD
)或 dd
(需要编译 dd
)。您丢弃的字节越多,此方法就越慢。尽管如此,与 fork 和执行外部二进制文件相比,生成随机字节通常相当快,因此丢弃大量字节不会造成太大伤害。例如,以下代码片段将生成一个介于 0 和 65535 之间的随机数:
n=65536
while [ $n -ge 65536 ]; do
n=1$(</dev/urandom tr -dc 0-9 | dd bs=5 count=1 2>/dev/null)
n=$((n-100000))
done
请注意,由于缓冲,tr
将处理比 dd
最终保留的字节多得多的字节。 BusyBox 的 tr
一次读取一个缓冲区(至少 512 字节),并在输入缓冲区完全处理时刷新其输出缓冲区,因此上面的命令总是从 读取至少 512 字节/dev/urandom
(很少有更多,因为 512 个输入字节的预期取值是 20 个十进制数字)。
如果您需要一个独特的可打印字符串,只需丢弃非 ASCII 字符,也许还有一些烦人的标点符号:
nonce=$(</dev/urandom tr -dc A-Za-z0-9-_ | head -c 22)
在这种情况下,我会认真考虑编写一个小型专用 C 程序。这是一个读取四个字节并输出相应的十进制数的方法。它不依赖于系统调用 read
和 write
的包装器以外的任何 libc 函数,因此您可以获得非常小的二进制文件。支持在命令行上作为十进制整数传递的变量 cap 留作练习;它将花费您数百字节的代码(如果您的目标大到足以运行 Linux,则无需担心)。
#include <stddef.h>
#include <unistd.h>
int main () {
int n;
unsigned long x = 0;
unsigned char buf[4];
char dec[11]; /* Must fit 256^sizeof(buf) in decimal plus one byte */
char *start = dec + sizeof(dec) - 1;
n = read(0, buf, sizeof(buf));
if (n < (int)sizeof(buf)) return 1;
for (n = 0; n < (int)sizeof(buf); n++) x = (x << 8 | buf[n]);
*start = '\n';
if (x == 0) *--start = '0';
else while (x != 0) {
--start;
*start = '0' + (x % 10);
x = x / 10;
}
while (n = write(1, start, dec + sizeof(dec) - start),
n > 0 && n < dec + sizeof(dec) - start) {
start += n;
}
return n < 0;
}
关于linux - 如何在 BusyBox shell 中生成随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7642743/