#1 Le 05/07/2021, à 11:48
- Tawal
[Résolu] Bash - Nombres aléatoires
Hello,
Je cherche à générer à chaque lancement d'un script une séquence (la plus unique possible) de nombres aléatoires.
Je me suis penché sur la fonction RANDOM de bash qui génère un nombre "aléatoire" entre 0 et 32767.
Mais la séquence de nombres aléatoires est dépendante de la "graine" de la fonction, exemple :
$ RANDOM=1
$ echo $RANDOM
16807
$ echo $RANDOM
15089
$ echo $RANDOM
11481
$
$ RANDOM=2
$ echo $RANDOM
846
$ echo $RANDOM
30178
$ echo $RANDOM
22963
$
$ RANDOM=1
$ echo $RANDOM
16807
$ echo $RANDOM
15089
$ echo $RANDOM
11481
$
$ RANDOM=2
$ echo $RANDOM
846
$ echo $RANDOM
30178
$ echo $RANDOM
22963
$
On voit bien que la graine génère la même séquence à chaque fois.
Pour pallier à ce souci, je fais :
RANDOM=$RANDOM
echo $RANDOM
Ainsi, la graine est "aléatoire" et donc la séquence générée aussi. Mais, en fait, ce n'est qu'un tirage de séquences parmi un lot fini.
Comment générer de "vrai" nombres aléatoires, ou du moins des nombres les plus imprévisibles possible en bash ?
Je vous remercie
Dernière modification par Tawal (Le 05/07/2021, à 12:48)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#2 Le 05/07/2021, à 11:57
- Nuliel
Re : [Résolu] Bash - Nombres aléatoires
Bonjour,
Le fait d'utiliser la même graine entraîne toujours la même suite finie. D'ailleurs c'est vrai pour tous les langages.
Généralement, on utilise le nombre de secondes depuis le 1er janvier 1970 pour initialiser la graine ce qui permet d'avoir des suites différentes.
Après tu peux aussi voir du côté de /dev/urandom si tu veux des nombres plus aléatoires (les générateurs "plus" aléatoires se basent sur des relevés de capteur du pc il me semble, /dev/urandom ne bloquerait pas l'exécution du script en cas d'entropie trop faible contrairement à /dev/random)
Dernière modification par Nuliel (Le 05/07/2021, à 11:59)
Hors ligne
#3 Le 05/07/2021, à 12:05
- Watael
Re : [Résolu] Bash - Nombres aléatoires
Généralement, on utilise le nombre de secondes depuis le 1er janvier 1970 pour initialiser la graine ce qui permet d'avoir des suites différentes.
+1
KISS!
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#4 Le 05/07/2021, à 12:40
- MicP
Re : [Résolu] Bash - Nombres aléatoires
Bonjour
…une séquence (la plus unique possible) …
Il y a le générateur d'UUID :
michel@debbull:~$ dbus-uuidgen
f127d30402c700ad94fcaf5860e2eefa
michel@debbull:~$
Hors ligne
#5 Le 05/07/2021, à 12:47
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Merci de vos réponses.
En fait, je me suis rendu compte que mon script "tirait" parfois une même séquence de nombres "aléatoires".
S'il suffit d'avoir un nombre différent pour la graine afin de s'assurer de l'unicité de la séquence aléatoire, alors je comprends l'initialisation de la graine par le nombre de secondes depuis 01.01.1970
Même si en réfléchissant, on pourrait prédire les séquences par avance : j'ai telle séquence à t donné, alors dans 10s j'aurai à coup sûr cette autre telle séquence.
Ce qui m'importe, c'est que chaque séquence soit différente de la précédente (et donc de la suivante par récurrence).
Et donc ta réponse Nuliel satisfait complètement ma demande.
Du coup, l’initialisation de la graine devient :
RANDOM=$(date +%s)
edit : ou plutôt :
printf -v RANDOM '%(%s)T'
Merci Watael - voir #14
Merci.
Dernière modification par Tawal (Le 05/07/2021, à 15:58)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#6 Le 05/07/2021, à 13:01
- Nuliel
Re : [Résolu] Bash - Nombres aléatoires
Même si en réfléchissant, on pourrait prédire les séquences par avance : j'ai telle séquence à t donné, alors dans 10s j'aurai à coup sûr cette autre telle séquence.
Complètement, on peut utiliser des générateurs pseudo aléatoires classiques lorsque le fait de pouvoir prévoir ce que va sortir le générateur ne dérange pas, mais lorsqu'on a vraiment besoin d'un truc sécurisé (typiquement quand le générateur fait partie d'un système cryptographique), on utilise des générateurs différents qui sont faits pour. A noter que ces générateurs plus sécurisés font baisser l'entropie, ce qui pose problème lorsqu'ils sont trop souvent utilisés (une entropie plus basse entraîne des nombres moins aléatoires).
Par exemple le module random de python utilise en interne le twister de Mersenne (précisément MT19937), qui peut être cassé en connaissant les 624 premières sorties du générateur (ça permet de retrouver l'état interne du générateur et ainsi recréer un deuxième générateur identique), ce qui explique pourquoi la doc python précise que le module random ne doit pas être utilisé pour des trucs sécurisés. Dans le cas de python, il faut utiliser le module secrets
Dernière modification par Nuliel (Le 05/07/2021, à 13:06)
Hors ligne
#7 Le 05/07/2021, à 13:30
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Merci de ces précisions Nuliel.
Non ce n'est pas pour de la sécurité, d'où mon contentement
@MicP : désolé, je n'avais pas vu ta réponse.
Je ne connais pas ce générateur.
Et le traitement qui doit suivre pour obtenir un nombre compris entre 2 bornes (inclues ou exclues) est un tantinet plus lourd qu'avec la fonction RANDOM de bash. Merci tout de même
Dernière modification par Tawal (Le 05/07/2021, à 13:32)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#8 Le 05/07/2021, à 13:36
- MicP
Re : [Résolu] Bash - Nombres aléatoires
Pour une valeur décimale comprise entre 0 et 32767
Je prends seulement les 4 premiers caractères hexa de l'UUID généré
et je fais un AND avec la valeur 32767
hexNum="$(dbus-uuidgen)"; echo $((32767 & 0x${hexNum::4}))
=======
Pour une valeur décimale comprise entre 0 et 65535
Je prends seulement les 4 premiers caractères hexa de l'UUID généré
et je fais un AND avec la valeur 65535
hexNum="$(dbus-uuidgen)"; echo $((65535 & 0x${hexNum::4}))
=======
Pour une valeur décimale comprise entre 0 et 1048575
Je prends seulement les 5 premiers caractères hexa de l'UUID généré
et je fais un AND avec la valeur 1048575
hexNum="$(dbus-uuidgen)"; echo $((1048575 & 0x${hexNum::5}))
Dernière modification par MicP (Le 05/07/2021, à 13:57)
Hors ligne
#9 Le 05/07/2021, à 13:53
- geole
Re : [Résolu] Bash - Nombres aléatoires
od -Ad -N8 -t u8 /dev/random | head -1 cut -c '10-27'
for (( j=0; j < 1000000; j++ )); do
> od -Ad -N8 -t u8 /dev/random | head -1 | cut -c '10-27' >>Fich
> done
a@b:~$ uniq -d Fich
a@b:~$
Dernière modification par geole (Le 05/07/2021, à 17:12)
Les grilles de l'installateur https://doc.ubuntu-fr.org/tutoriel/inst … _subiquity
"gedit admin:///etc/fstab" est proscrit, utilisez "pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY xdg-open /etc/fstab" Voir https://doc.ubuntu-fr.org/gedit
Les partitions EXT4 des disques externes => https://forum.ubuntu-fr.org/viewtopic.p … #p22697248
En ligne
#10 Le 05/07/2021, à 14:07
- MicP
Re : [Résolu] Bash - Nombres aléatoires
Pour un générateur de nombre aléatoire basé sur un circuit électronique,
j'avais pensé compter (avec RAZ quand maxi atteint) les impulsion du bruit généré par une diode zener (dans la région de rupture d'avalanche)
Dernière modification par MicP (Le 05/07/2021, à 14:10)
Hors ligne
#11 Le 05/07/2021, à 15:06
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Oui, j'avais lu quelque part que le meilleur "aléatoire" (en tout cas le plus imprévisible) venait du bruit : parasites radiographique et électromagnétique, rayonnement gamma etc
Merci pour vos exemples sympathiques de génération de nombres aléatoires.
C'est vrai que j'ai un peu titillé pour les bornes, quand on connaît le "range" du tirage aléatoire, il est facile de le ramener dans les bornes voulues.
Personnellement, je préfère la solution od car plus maîtrisable (à mon sens) par ses paramètres/options.
En plus, le générateur d'aléatoire peut-être /dev/urandom qui, comme l'explique Nuliel, donne un coté "plus" aléatoire.
Les générateurs /dev/random et /dev/urandom ont un coté plus aléatoire que la fonction RANDOM de bash. (voir ci dessous - Merci Nuliel)
Dernière modification par Tawal (Le 05/07/2021, à 15:27)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#12 Le 05/07/2021, à 15:19
- Nuliel
Re : [Résolu] Bash - Nombres aléatoires
Par plus aléatoire, je parlais par rapport au générateur que tu utilises, car /dev/urandom et /dev/random c'est la même chose (hormis que le premier sort des nombres même si l'entropie est trop faible contrairement au deuxième qui s'arrête lorsque l'entropie est trop faible)
Hors ligne
#13 Le 05/07/2021, à 15:25
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Merci de rectifier (et pour moi et pour les autres, ne pas laisser traîner des infos erronées )
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#14 Le 05/07/2021, à 15:41
- Watael
Re : [Résolu] Bash - Nombres aléatoires
Du coup, l’initialisation de la graine devient :
RANDOM=$(date +%s)
printf -v RANDOM '%(%s)T'
et hop! une commande externe de plus en moins.
merci bash.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#15 Le 05/07/2021, à 15:53
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Merci Watael, un "help printf" m'a bien aidé à comprendre ta commande
Solution adoptée par "amour" des primitives ...
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#16 Le 08/07/2021, à 11:54
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Re,
Finalement, j'ai opté pour cette solution, adaptée à mes besoins :
num_alea=$(( $(od -Ad -N7 -t u8 /dev/urandom | head -1 | cut -c '12-27')%$limite +1 ))
Pour un "tirage" des nombres aléatoires compris entre 1 et $limite (bornes incluses).
Dernière modification par Tawal (Le 08/07/2021, à 11:55)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#17 Le 08/07/2021, à 13:09
- Watael
Re : [Résolu] Bash - Nombres aléatoires
od -Ad -N7 -t u8 /dev/urandom | sed -rn '1{s/^.{12}//p}'
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#18 Le 08/07/2021, à 18:40
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Ah oui, tu as le droit de faire comme cela
Non, sérieux, pour être sûr de bien comprendre la regex (option -r de sed) et l'expression de sed :
Substitution des 12 premiers caractères par "rien" et affichage, le tout que pour la ligne 1.
Merci, ça fait un pipe de moins.
Edit: ou comme ceci :
od -Ad -N7 -t u8 /dev/urandom | awk 'NR==1 {print $2}'
Dernière modification par Tawal (Le 08/07/2021, à 18:52)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#19 Le 08/07/2021, à 19:04
- Watael
Re : [Résolu] Bash - Nombres aléatoires
Substitution des 12 premiers caractères par "rien" et affichage, le tout que pour la ligne 1.
c'est ça.
ah, oui. awk, c'est bien.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#20 Le 08/07/2021, à 20:03
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Merci pour la confirmation
Du coup, je garde la formule avec awk, elle est quand même plus claire (pour moi).
Merci pour la réflexion qui m'amène à une autre solution
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#21 Le 08/07/2021, à 23:34
- LeoMajor
Re : [Résolu] Bash - Nombres aléatoires
salut; il y a l'embarras du choix.
A/
uuidgen,
shuf (coreutils),
:~$ min=1; max=100; shuf -i "$min-$max" -n5 --random-source /dev/random
10
31
55
2
91
variante shuf + uuidgen
:~$ c=0; until [ "$c" -ge 10 ]; do ((c++)); r=$(shuf -i 1-8 -n1 --random-source /dev/random); alea=$(uuidgen -r); alea=${alea::$r}; printf "%d:%s:%d\n" "$c" "$alea" 0x"$alea"; done
1:59abb1:5876657
2:9:9
3:2b:43
4:ef1:3825
5:4be8abf9:1273539577
6:c2:194
7:99aa89:10070665
8:211b5d0:34715088
9:bf2:3058
10:f0344b0:251872432
unicode decimal au hasard
:~$ while IFS=$'\0' read -n1; do printf "%s %d " "$REPLY" "'$REPLY"; done < <(utfout '\g' -r9); echo
? 120797 자 51088 ? 119245 휋 55051 洃 27907 ? 172732 漫 28459 ? 119652 휤 55076 ? 151209
rand ( qui intègre unique )
:~$ rand -M 101 -N 10 -u
26 80 54 23 38 16 53 35 94 70
...
B/ /dev/random est intéressant si tu peuples, regénères avec haveged, randomsound, rng-tools (le plus capricieux des 3)
:~$ systemctl status haveged.service
● haveged.service - Entropy daemon using the HAVEGE algorithm
Loaded: loaded (/lib/systemd/system/haveged.service; enabled; vendor preset: enabled)
Active: active (running) since jeu. 2021-07-08 23:03:12 CEST; 1h 22min ago
Docs: man:haveged(8)
http://www.issihosts.com/haveged/
Main PID: 7309
CGroup: /system.slice/haveged.service
└─7309 n/a
:~$ systemctl status randomsound.service
● randomsound.service - LSB: Random Sound
Loaded: loaded (/etc/init.d/randomsound; bad; vendor preset: enabled)
Active: active (running) since jeu. 2021-07-08 23:01:41 CEST; 1h 25min ago
Docs: man:systemd-sysv-generator(8)
CGroup: /system.slice/randomsound.service
├─1213 n/a
└─9652 n/a
:~$ systemctl status rngd.service
● rngd.service - Hardware RNG Entropy Gatherer Daemon
Loaded: loaded (/etc/systemd/system/rngd.service; enabled; vendor preset: enabled)
Active: active (running) since jeu. 2021-07-08 23:01:40 CEST; 1h 25min ago
Main PID: 1218
CGroup: /system.slice/rngd.service
└─1218 n/a
cat /proc/sys/kernel/random/entropy_avail
3805
Hors ligne
#22 Le 09/07/2021, à 11:48
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Intéressant
Sans rien installer de plus, il ne me reste que les solutions avec shuf et uuidgen.
Merci.
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#23 Le 09/07/2021, à 14:54
- credenhill
Re : [Résolu] Bash - Nombres aléatoires
hello
od sans pipe
$ od -vAn -N7 -t u8 /dev/urandom
23002729082305994
$ od -vAn -N7 -t u8 /dev/urandom
933934716307164
$ od -vAn -N7 -t u8 /dev/urandom
17137229049192107
Hors ligne
#24 Le 09/07/2021, à 15:27
- Tawal
Re : [Résolu] Bash - Nombres aléatoires
Cool
Mais les espaces devant les nombres ne posent pas soucis pour le traitement numéraire ? Non aucuns
Dernière modification par Tawal (Le 09/07/2021, à 15:29)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#25 Le 10/07/2021, à 10:33
- LeoMajor
Re : [Résolu] Bash - Nombres aléatoires
shuf ne fait pas de doublons (uniq)
:~$ shuf -i 1-10 -n 100
apg générateur de mots de passe (/dev/random)
~$ apg -a 1 -M n -m 1 -x 12 -n 10
88221
75732367
04700095753
93671
944
097169361
610607442
820294
7917
9739010616
openssl souvent installé sur les serveurs
:~$ unset ns c; c=0; ns=($(until [ "$c" -ge 20 ]; do ((c++)); printf "%d\n" 0x$(openssl rand -rand /dev/random:/dev/urandom -hex $(shuf -i 1-7 -n1 --random-source /dev/random) 2>/dev/null); done))
:~$ for ((i=0;i<=19;i++)); do echo "${ns[$i]}"; done
575643333848
1020645374
55195
5753081
10349364
14847810
45405
41362829266635630
91
32340
...
Hors ligne