$RANDOM
et od
sont des fonctionnalités facultatives dans BusyBox, je suppose, compte tenu de votre question, qu'elles ne sont pas incluses dans votre fichier binaire. Vous mentionnez dans un commentaire que /dev/urandom
est présent, c'est bien, cela signifie que ce que vous devez faire est de récupérer des octets sous une forme utilisable, et non le problème beaucoup plus difficile de la mise en œuvre d'un générateur de nombres aléatoires. Notez que vous devez utiliser /dev/urandom
et non /dev/random
, voir Est-ce qu'un rand de /dev/urandom est sécurisé pour une clé de connexion ?.
Si vous avez tr
ou sed
, vous pouvez lire les octets de /dev/urandom
et supprimez tout octet qui n'est pas un caractère souhaitable. Vous aurez également besoin d'un moyen d'extraire un nombre fixe d'octets d'un flux :soit head -c
(nécessitant FEATURE_FANCY_HEAD
à activer) ou dd
(nécessitant dd
à compiler). Plus vous supprimez d'octets, plus cette méthode sera lente. Pourtant, générer des octets aléatoires est généralement assez rapide par rapport au fork et à l'exécution de binaires externes, donc en supprimer beaucoup ne fera pas beaucoup de mal. Par exemple, l'extrait de code suivant produira un nombre aléatoire entre 0 et 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
Notez qu'en raison de la mise en mémoire tampon, tr
va traiter un peu plus d'octets que ce que dd
finira par tenir. tr
de BusyBox lit un tampon (au moins 512 octets) à la fois et vide son tampon de sortie chaque fois que le tampon d'entrée est entièrement traité, de sorte que la commande ci-dessus lira toujours au moins 512 octets à partir de /dev/urandom
(et très rarement plus puisque la prise attendue de 512 octets d'entrée est de 20 chiffres décimaux).
Si vous avez besoin d'une chaîne imprimable unique, supprimez simplement les caractères non ASCII et peut-être certains caractères de ponctuation ennuyeux :
nonce=$(</dev/urandom tr -dc A-Za-z0-9-_ | head -c 22)
Dans cette situation, j'envisagerais sérieusement d'écrire un petit programme C dédié. En voici un qui lit quatre octets et affiche le nombre décimal correspondant. Il ne repose sur aucune fonction libc autre que les wrappers pour les appels système read
et write
, vous pouvez donc obtenir un très petit fichier binaire. La prise en charge d'une variable cap passée sous forme d'entier décimal sur la ligne de commande est laissée en exercice; cela vous coûtera des centaines d'octets de code (pas quelque chose dont vous devez vous soucier si votre cible est assez grande pour exécuter 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;
}
</dev/urandom sed 's/[^[:digit:]]\+//g' | head -c10