Générer un nombre aléatoire

Générer un nombre aléatoire en héxadécimal et en décimal

Problématique

Il peut être parfois utile de générer un nombre aléatoire dans un shell sans pour autant installer de programmes spécifiques. Pour, par exemple, générer une clef WEP.

Solution

Générer un nombre hexadécimal

Il existe un générateur de données aléatoires :

dd if=/dev/urandom count=1

Remarque

Il existe aussi le pseudo périphérique /dev/urandom pour générer des données aléatoires.

Cette commande va générer 512 octets aléatoires. Mais ce générateur ne s'occupe pas de savoir si les données générées sont accessibles par un clavier et donc utilisables.

Pour améliorer ces données aléatoires et les rendre utilisables, il faut donc les transformer.

dd if=/dev/urandom count=1 | md5

Par exemple, donnera :

1+0 records in
1+0 records out
512 bytes transferred in 0.000346 secs (1480003 bytes/sec)
fc91837fa2bdba1f9fe985452fdb925e

ou bien, dans le cas d'un système comme Linux qui n'a pas les mêmes encapsulations de commandes :

dd if=/dev/urandom count=1 | openssl dgst -md5

qui donnerait :

1+0 records in
1+0 records out
512 bytes transferred in 0.000346 secs (1480003 bytes/sec)
(stdin)= fc91837fa2bdba1f9fe985452fdb925e

que nous pourrions ensuite nettoyer de la façon suivante :

dd if=/dev/urandom count=1 | openssl dgst -md5 | cut -d'=' -f2- | tr -d ' '

cut sert à récupérer la partie après le "=" (et toute la ligne s'il ne trouve pas le caractère. tr sert à supprimer tous les blancs (non significatifs).

Et nous obtiendrions alors le même résultat :

fc91837fa2bdba1f9fe985452fdb925e

C'est encore un peu long, mais plus aisément utilisable. Les lignes inutiles (les 3 premières lignes) qui apparaissent ne sont en réalité pas sur la même sortie que le résultat. Elles ne gênent donc pas pour la suite.

dd if=/dev/urandom count=1 | md5 | cut -c-26

va générer un nombre aléatoire hexadécimal 26 caractères de long. Les 26 premiers caractères.

dd if=/dev/urandom count=1 | md5 | cut -c 5-8

va générer un nombre héxadécimal de 4 caractères de long, du 5ème au 8ème caractère de la chaîne.

Générer un nombre décimal

Méthode longue

Le nombre décimal est généré à partir du nombre aléatoire hexadécimal. En effet, l'hexadécimal est codé comme suit :

Hexa

décimal

0

0

1

1

2

2

3

3

4

4

5

5

6

6

7

7

8

8

9

9

A

10

B

11

C

12

D

13

E

14

F

15

L'utilité de l'hexadécimal résuidant dans la capacité à représenter un octet sur 2 caractères. Par exemple, le nombre 255 est noté 11111111 en binaire et ff en hexadécimal.

Comme pour un nombre décimal (base 10), par exemple 1456, qui peut être décomposé en 1 x 1000 + 4 x 100 + 5 x 10 + 6, soit donc 1 x 103 + 4 x 102 + 5 x 101 + 6 x 100, un nombre hexadécimal sera représenté en base 16.

Remarque

En général, un nombre hexadécimal possède une longueur paire, sinon, on complète à gauche avec des 0. FE145 est en fait 0FE145.

Pour convertir un nombre hexadécimal en décimal, il suffit d'effectuer l'opération suivante :

FE145 = F x 164 + E x 163 + 1 x 162 + 4 x 161 + 5 x 160

FE145 = 15 x 164 + 14 x 163 + 1 x 162 + 4 x 161 + 5

FE145 = 15 x 65536 + 14 x 4096 + 1 x 256 + 4 x 16 + 5

FE145 = 983040 + 57344 + 256 + 64 + 5

FE145 = 1040709

Il suffit d'intégrer cette opération dans un shell :

#!/bin/sh
#commençons par générer un nombre en hexadecimal de 26 caracères de long, par ex.
dd if=/dev/urandom count=1 | md5 | cut -c-26

#convertissons dans une boucle

Méthode rapide

Il y a plus simple, grâce à la calculatrice bc :

dd if=/dev/urandom count=1 | md5 | cut -c 5-6 | bc

ne convertit rien ou provoque une erreur car l'hexadecimal doit être présenté en majuscule :

dd if=/dev/urandom count=1 | md5 | cut -c 5-6 | tr '[a-z]' '[A-Z]' | bc

La configuration par défaut de bc est la sortie en base 10 (obase=10 : décimal). Il va spontanément convertir notre résultat hexadécimal en décimal.

Pour aller plus loin

De la même façon, on peut générer des mots de passe aléatoires