Comment générer des nombres aléatoires en utilisant AShell (bash restreint)? J'utilise un binaire BusyBox sur l'appareil qui n'a pas od
ou $RANDOM
. Mon appareil a /dev/urandom
et /dev/random
.Comment générer des nombres aléatoires dans le shell BusyBox
Répondre
$RANDOM
et od
sont des fonctionnalités optionnelles dans BusyBox, je suppose étant donné votre question qu'ils ne sont pas inclus dans votre binaire. Vous mentionnez dans un commentaire que /dev/urandom
est présent, c'est bien, cela signifie que ce que vous devez faire est d'en récupérer des octets sous une forme utilisable, et pas le problème beaucoup plus difficile de l'implémentation d'un générateur de nombres aléatoires. Notez que vous devez utiliser /dev/urandom
et non /dev/random
, voir Is a rand from /dev/urandom secure for a login key?.
Si vous avez tr
ou sed
, vous pouvez lire les octets de /dev/urandom
et ignorer 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
pour être activé) ou dd
(nécessitant dd
pour être compilé). Plus vous rejetez d'octets, plus cette méthode sera lente. Pourtant, la génération d'octets aléatoires est généralement plutôt rapide en comparaison avec le bifurcation et l'exécution de binaires externes, donc en jeter un grand nombre ne fera pas trop mal. Par exemple, l'extrait 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 mise en mémoire tampon, tr
va traiter assez peu plus d'octets que ce dd
va finir par la tenue. BusyBox tr
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é, donc la commande ci-dessus lira toujours au moins 512 octets de /dev/urandom
(et très rarement plus depuis la prise attendue à partir de 512 octets d'entrée est 20 chiffres décimaux).
Si vous avez besoin d'une chaîne imprimable unique, tout jeter des 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, je voudrais sérieusement envisager d'écrire un petit programme dédié C . En voici un qui lit quatre octets et sort le nombre décimal correspondant. Il ne repose sur aucune autre fonction de libc que les wrappers pour les appels système read
et write
, donc vous pouvez obtenir un très petit binaire. La prise en charge d'une variable variable transmise sous la forme d'un nombre décimal entier sur la ligne de commande est conservée en tant qu'exercice; cela vous coûtera des centaines d'octets de code (ce qui ne vous inquiète pas si votre cible est assez grande pour faire tourner 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;
}
J'ai amélioré votre premier extrait et le mettre dans une réponse séparée ci-dessous, car les commentaires ne semblent pas supporter les blocs de code. – escitalopram
@escitalopram Merci pour les corrections. Pour référence future, vous êtes [bienvenue et même encouragé à éditer les messages pour corriger les erreurs mineures] (http://stackoverflow.com/help/editing) (attention, certains [si] utilisateurs le détestent lorsque vous modifiez leur code brisé - Je ne suis pas un de ceux-ci cependant. – Gilles
/dev/random ou/dev/urandom sont susceptibles d'être présents.
Une autre option consiste à écrire un petit programme C qui appelle srand(), puis rand().
oui/dev/urandom et/dev/random sont présents, mais comment les utiliser sans od. Je peux lire ensuite en utilisant dd. Alors qu'est-ce que je fais? – abc
'/ dev/random' contient des données aléatoires (caractères de 256 bits). 'head -c N/dev/random' vous donne' N' octets de données aléatoires. – Dennis
</dev/urandom sed 's/[^[:digit:]]\+//g' | head -c10
Cela donne parfois des espaces dans le nombre généré, comme "6 60 09807" ou "076 2 15". –
I Tried premier extrait de Gilles avec BusyBox 1,22.1 et moi avons des patchs, qui ne cadrait pas avec un commentaire:
while [ $n -gt 65535 ]; do
n=$(</dev/urandom tr -dc 0-9 | dd bs=5 count=1 2>/dev/null | sed -e 's/^0\+//')
done
- La condition de la boucle doit vérifier supérieure à la valeur maximale, sinon il y aura 0 exécutions.
- Je réduit au silence
stderr
dedd
- zéros, a été enlevé ce qui pourrait conduire à des surprises dans des contextes où interprétés comme octal (par exemple
$(())
)
Hexdump et dc sont tous deux disponibles avec busybox. Utilisez/dev/urandom pour la plupart aléatoire ou/dev/random pour mieux aléatoire. Chacune de ces options est meilleure que $ RANDOM et sont toutes deux plus rapides que la recherche de caractères imprimables en boucle.
32 bits nombre aléatoire décimales:
CNT=4
RND=$(dc 10 o 0x$(hexdump -e '"%02x" '$CNT' ""' -n $CNT /dev/random) p)
hex nombre aléatoire 24 bits:
CNT=3
RND=0x$(hexdump -e '"%02x" '$CNT' ""' -n $CNT /dev/random)
Pour obtenir de plus petits nombres, changer le format de la chaîne de format hexdump et le nombre d'octets cet hexdump lit.
- 1. Comment générer des nombres aléatoires dans Java
- 2. Générer des nombres aléatoires uniques
- 3. Générer des nombres décimaux aléatoires
- 4. Générer des nombres aléatoires Jquery
- 5. Comment générer des nombres aléatoires en Javascript?
- 6. Comment générer des nombres aléatoires différents?
- 7. Générer des nombres aléatoires 1-100
- 8. générer des nombres aléatoires sans répétition consécutive
- 9. android - générer des nombres aléatoires sans répétition
- 10. Générer des nombres aléatoires en PHP Tableau
- 11. Générer des nombres aléatoires multiples uniques
- 12. générer des nombres aléatoires en Array
- 13. générer des nombres aléatoires en C
- 14. générer des nombres aléatoires en C++
- 15. comment générer des nombres aléatoires avec une séquence dans R
- 16. Comment générer des nombres positifs et négatifs aléatoires dans VBA
- 17. Comment générer des nombres réellement aléatoires (NOT pseudo) dans Linux
- 18. Comment générer deux nombres aléatoires sur 4?
- 19. Générer des nombres aléatoires de -n à n dans C
- 20. Comment générer des nombres aléatoires avec r.nextInt() sauf un nombre?
- 21. Comment générer des nombres aléatoires multivariés avec différentes distributions marginales?
- 22. Comment puis-je générer des nombres aléatoires en Python?
- 23. Génération de nombres aléatoires avec awk dans le shell BASH
- 24. java: générer des nombres aléatoires dans une boucle
- 25. Générer des nombres aléatoires non répétitifs dans Ruby
- 26. Générer deux nombres aléatoires pour l'échantillonnage RANSAC
- 27. accélérer générer N nombres aléatoires uniques code
- 28. traitant des nombres aléatoires dans android
- 29. comment puis-je générer n nombres aléatoires uniques dans sybase
- 30. Comment s'interfacer avec le shell (BusyBox) dans l'application Android
Est-ce une faute de frappe? "Vous utilisez busybox et vous n'avez donc pas '' od '"? Busybox _includes_ 'od' (et ça fait longtemps). Appelez simplement 'busybox od' directement si le _link_' od -> busybox' n'existe pas. –
@FrankH. Presque tous les composants de BusyBox sont facultatifs, y compris 'od' et' $ RANDOM'. – Gilles