linux - 如何在 BusyBox shell 中生成随机数

标签 linux shell random embedded busybox

如何使用 AShell(受限 bash)生成随机数?我在没有 od$RANDOM 的设备上使用 BusyBox 二进制文件。我的设备有 /dev/urandom/dev/random

最佳答案

$RANDOMod 是 BusyBox 中的可选功能,鉴于您的问题,我假设它们不包含在您的二进制文件中。您在评论中提到 /dev/urandom 存在,这很好,这意味着您需要做的是以可用形式从中检索字节,而不是实现一个更困难的问题随机数发生器。请注意,您应该使用 /dev/urandom 而不是 /dev/random,请参阅 Is a rand from /dev/urandom secure for a login key? .

如果你有 trsed,你可以从 /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 程序。这是一个读取四个字节并输出相应的十进制数的方法。它不依赖于系统调用 readwrite 的包装器以外的任何 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/

相关文章:

linux - 查找 Linux 安装的总大小

linux - shell脚本不返回任何输入

objective-c - OSX 以 root 身份以编程方式启动 launchctl

css - sass 看多个目录

ruby-on-rails - 在 minitest 中测试 postgres "RANDOM()"

algorithm - 使用单因素或多因素求解算法抛硬币?

python - 在 Linux 程序中嵌入 Python

r - 无法在 Linux 服务器上安装任何 R 包

linux - 如何使用 AWK 合并两个文件?

ios - 如何创建几乎与我的 GameScene 接壤的坐标?