$RANDOM
и od
являются дополнительными функциями BusyBox, я предполагаю, что, учитывая ваш вопрос, они не включены в ваш двоичный файл.В комментарии вы упоминаете, что /dev/urandom
присутствует, это хорошо, это означает, что вам нужно извлечь из него байты в удобной форме, а не намного более сложную задачу реализации генератора случайных чисел.Обратите внимание, что вы должны использовать /dev/urandom
, а не /dev/random
, см. Является ли ранд из / dev / urandom безопасным для ключа входа в систему? .
Если у вас tr
или sed
, вы можете прочитать байты из /dev/urandom
и отбросить любой байт, который не является желательным символом.Вам также потребуется способ извлечения фиксированного количества байтов из потока: либо head -c
(требующий включения FEATURE_FANCY_HEAD
), либо dd
(требующий компиляции dd
).Чем больше байтов вы отбрасываете, тем медленнее будет этот метод.Тем не менее, генерация случайных байтов обычно довольно быстрая по сравнению с разветвлением и выполнением внешних двоичных файлов, поэтому отказ от многих из них не повредит.Например, следующий фрагмент даст случайное число от 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
сохраняя.tr
BusyBox читает за один раз буфер (не менее 512 байт) и очищает свой выходной буфер всякий раз, когда входной буфер полностью обрабатывается, поэтому приведенная выше команда всегда будет читать не менее 512 байт из /dev/urandom
(и очень редкопоскольку ожидаемый результат из 512 входных байтов составляет 20 десятичных цифр).
Если вам нужна уникальная печатная строка, просто отбросьте не-ASCII-символы и, возможно, некоторые раздражающие знаки пунктуации:
nonce=$(</dev/urandom tr -dc A-Za-z0-9-_ | head -c 22)
В этой ситуации я бы серьезно подумал о написании небольшой специализированной программы на Си.Вот тот, который читает четыре байта и выводит соответствующее десятичное число.Он не зависит от какой-либо функции libc, кроме оболочек для системных вызовов read
и write
, поэтому вы можете получить очень маленький двоичный файл.Поддержка переменной 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;
}