Vous observez une combinaison du comportement particulier de dd
avec le comportement particulier du /dev/random
de Linux . Soit dit en passant, les deux sont rarement le bon outil pour le travail.
/dev/random
de Linux renvoie les données avec parcimonie. Il est basé sur l'hypothèse que l'entropie dans le générateur de nombres pseudo-aléatoires s'éteint à un rythme très rapide. Étant donné que la collecte de nouvelle entropie est lente, /dev/random
abandonne généralement seulement quelques octets à la fois.
dd
est un vieux programme grincheux initialement destiné à fonctionner sur des périphériques à bande. Lorsque vous lui dites de lire un bloc de 1 Ko, il tente de lire un bloc. Si la lecture renvoie moins de 1024 octets, difficile, c'est tout ce que vous obtenez. Donc dd if=/dev/random bs=1K count=2
fait deux read(2)
appels. Puisqu'il lit à partir de /dev/random
, les deux read
les appels ne renvoient généralement que quelques octets, en nombre variable en fonction de l'entropie disponible. Voir aussi Quand dd convient-il pour copier des données ? (ou, quand read() et write() sont partiels)
À moins que vous ne conceviez un programme d'installation ou un cloneur de système d'exploitation, vous ne devez jamais utiliser /dev/random
sous Linux, toujours /dev/urandom
. Le urandom
la page de manuel est quelque peu trompeuse ; /dev/urandom
est en fait adapté à la cryptographie, voire à la génération de clés à longue durée de vie. La seule restriction avec /dev/urandom
est qu'il doit être alimenté avec une entropie suffisante; Les distributions Linux enregistrent normalement l'entropie entre les redémarrages, donc la seule fois où vous n'aurez peut-être pas assez d'entropie, c'est sur une nouvelle installation. L'entropie ne s'estompe pas en pratique. Pour plus d'informations, consultez Est-ce qu'un rand de /dev/urandom est sécurisé pour une clé de connexion ? et alimenter /dev/random entropy pool ?.
La plupart des utilisations de dd
sont mieux exprimés avec des outils tels que head
ou tail
. Si vous voulez 2 Ko d'octets aléatoires, exécutez
head -c 2k </dev/urandom >rand
Avec les anciens noyaux Linux, vous pourriez vous en sortir
dd if=/dev/urandom of=rand bs=1k count=2
car /dev/urandom
heureusement retourné autant d'octets que demandé. Mais ce n'est plus vrai depuis le noyau 3.16, il est désormais limité à 32 Mo.
En général, lorsque vous devez utiliser dd
pour extraire un nombre fixe d'octets et que son entrée ne provient pas d'un fichier normal ou d'un périphérique bloc, vous devez lire octet par octet :dd bs=1 count=2048
.
De man 4 random
sur un boitier RHEL 5 :
Lors de la lecture, le périphérique /dev/random ne renverra que des octets aléatoires dans le nombre estimé de bits de bruit dans le pool d'entropie.
Je reçois des fichiers de taille 213 octets sur cette machine. Retour à l'homme 4 au hasard :
Une fois lu, le périphérique /dev/urandom renverra autant d'octets que demandé.
Je reçois 2048 octets à chaque invocation de dd if=/dev/urandom of=rand bs=1K count=2
Je conclus que la différence est due à la quantité d'entropie que votre machine génère entre les invocations de dd if=/dev/random ...
Pourquoi dd
supprimer des données ? ... Gilles a posé cette question engageante sur dd
:
Quand dd convient-il pour copier des données ? (ou, quand read() et write() sont partiels)
Voici un extrait de cette question :
*...il n'est pas difficile de mettre dd en faute; par exemple essayez ce code :**
yes | dd of=out bs=1024k count=10
et vérifiez la taille du fichier de sortie (il est probable qu'il soit bien inférieur à 10 Mo).
Mis à part mon commentaire (à la fin de votre question), quelque chose comme ça est intéressant à regarder... Il attrape vos octets dans le fichier $trnd
. J'ai choisi semi-arbitrairement bs=8
Déplacez votre souris et regardez-la accélérer.
Avec mon ordinateur inactif (AFK et aucune activité réseau), et après avoir épuisé le pool d'entropie, cela a pris 2 heures 12 minutes pour collecter seulement 1192 octets, à quel point je l'ai annulé.
Ensuite, avec le déplacement continu de la souris, cela a pris 1 minute relativement beaucoup plus courte 15 secondes pour collecter le même nombre d'octets.
Cela montre assez clairement que la collecte d'entropie n'est pas basée sur la vitesse du processeur, mais plutôt sur des événements aléatoires basé, et que mon système Ubuntu utilise la souris comme l'un de ses importants facteurs aléatoires.
get=2048
trnd=/tmp/$USER.rnd; >"$trnd"
while (( $(wc -c <"$trnd") < $get )) ;do
dd if=/dev/random bs=8 count=1 2>/dev/null >>"$trnd"
echo -n "itt: $((i+=1)) ct: "; wc -c <"$trnd"
done
truncate -s $get "$trnd"
echo -e "\nfinal count: "; wc -c <"$trnd"