$RANDOM
und od
optionale Funktionen in BusyBox sind, gehe ich angesichts Ihrer Frage davon aus, dass sie nicht in Ihrer Binärdatei enthalten sind. Sie erwähnen in einem Kommentar, dass /dev/urandom
vorhanden ist, das ist gut, es bedeutet, dass Sie Bytes in einer verwendbaren Form daraus abrufen müssen und nicht das viel schwierigere Problem der Implementierung eines Zufallszahlengenerators. Beachten Sie, dass Sie /dev/urandom
verwenden sollten und nicht /dev/random
, siehe Ist ein Rand von /dev/urandom sicher für einen Anmeldeschlüssel?.
Wenn Sie tr
haben oder sed
, können Sie Bytes von /dev/urandom
lesen und jedes Byte verwerfen, das kein erwünschtes Zeichen ist. Sie benötigen auch eine Möglichkeit, eine feste Anzahl von Bytes aus einem Stream zu extrahieren:entweder head -c
(erfordert FEATURE_FANCY_HEAD
aktiviert werden) oder dd
(erfordert dd
einkompiliert werden). Je mehr Bytes Sie verwerfen, desto langsamer wird diese Methode. Dennoch ist das Generieren zufälliger Bytes im Vergleich zum Forken und Ausführen externer Binärdateien normalerweise ziemlich schnell, sodass das Verwerfen vieler davon nicht sehr schaden wird. Das folgende Snippet erzeugt beispielsweise eine Zufallszahl zwischen 0 und 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
Beachten Sie, dass aufgrund der Pufferung tr
wird einige Bytes mehr verarbeiten als dd
wird am Ende behalten. tr
von BusyBox liest jeweils einen Puffer (mindestens 512 Bytes) und leert seinen Ausgabepuffer, wenn der Eingabepuffer vollständig verarbeitet ist, sodass der obige Befehl immer mindestens 512 Bytes von /dev/urandom
liest (und sehr selten mehr, da die erwartete Entnahme aus 512 Eingabebytes 20 Dezimalstellen beträgt).
Wenn Sie eine eindeutige druckbare Zeichenfolge benötigen, verwerfen Sie einfach Nicht-ASCII-Zeichen und möglicherweise einige lästige Satzzeichen:
nonce=$(</dev/urandom tr -dc A-Za-z0-9-_ | head -c 22)
In dieser Situation würde ich ernsthaft darüber nachdenken, ein kleines, dediziertes C-Programm zu schreiben. Hier ist einer, der vier Bytes liest und die entsprechende Dezimalzahl ausgibt. Es verlässt sich auf keine libc-Funktion außer den Wrappern für die Systemaufrufe read
und write
, sodass Sie eine sehr kleine Binärdatei erhalten können. Die Unterstützung einer variablen Obergrenze, die als dezimale Ganzzahl auf der Befehlszeile übergeben wird, bleibt als Übung; es kostet Sie Hunderte von Bytes Code (nichts, worüber Sie sich Sorgen machen müssen, wenn Ihr Ziel groß genug ist, um Linux auszuführen).
#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;
}
</dev/urandom sed 's/[^[:digit:]]\+//g' | head -c10