J'exécute la commande suivante sur un système Ubuntu:
dd if=/dev/random of=rand bs=1K count=2
Cependant, chaque fois que je l'exécute, je me retrouve avec un fichier d'une taille différente. Pourquoi est-ce? Comment puis-je générer un fichier d'une taille donnée rempli de données aléatoires?
/dev/random
se bloquera s'il n'y a pas assez d'entropie disponible pour générer le nombre de chiffres souhaité. il faut simplement du temps pour rassembler cette quantité de "randomité" aléatoire de haute qualité ... Soit utiliser/dev/urandom
pour une valeur "aléatoire" moins aléatoire, soit vérifier votre pool d'entropie (en boucle, et attendre au besoin) ...iflag=fullblock
Réponses:
Vous observez une combinaison du comportement particulier de
dd
avec le comportement particulier de Linux/dev/random
. Soit dit en passant, les deux sont rarement le bon outil pour le travail.Linux
/dev/random
retourne 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. Comme la collecte d'une nouvelle entropie est lente, elle/dev/random
n'abandonne généralement que quelques octets à la fois.dd
est un ancien 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. Fait doncdd if=/dev/random bs=1K count=2
deuxread(2)
appels. Puisqu'il lit/dev/random
, les deuxread
appels ne retournent généralement que quelques octets, en nombre variable selon l'entropie disponible. Voir aussi Quand dd convient-il pour copier des données? (ou, quand sont read () et write () partial)À moins que vous ne conceviez un programme d'installation ou un cloneur de système d'exploitation, vous ne devriez jamais utiliser
/dev/random
sous Linux, toujours/dev/urandom
. Laurandom
page de manuel est quelque peu trompeuse;/dev/urandom
est en fait adapté à la cryptographie, même pour générer des clés à longue durée de vie. La seule restriction/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 pourriez ne pas avoir suffisamment d'entropie est sur une nouvelle installation. L'entropie ne s'use pas en termes pratiques. Pour plus d'informations, lisez Un rand de / dev / urandom est-il sécurisé pour une clé de connexion? et alimentation / dev / pool d'entropie aléatoire? .La plupart des utilisations de
dd
sont mieux exprimées avec des outils tels quehead
outail
. Si vous voulez 2 Ko d'octets aléatoires, exécutezAvec les noyaux Linux plus anciens, vous pourriez vous en sortir avec
car
/dev/urandom
heureusement retourné autant d'octets que demandé. Mais cela ne l' est plus depuis le noyau 3.16, il est maintenant limité à 32Mo .En général, lorsque vous devez utiliser
dd
pour extraire un nombre fixe d'octets et son entrée ne provient pas d'un fichier régulier ou un périphérique de bloc, vous devez lire octet par octet:dd bs=1 count=2048
.la source
/dev/urandom
renvoie 32m perread()
.dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
Depuis
man 4 random
une box RHEL 5:J'obtiens des fichiers de taille 213 octets sur cette machine. Retour à l'homme 4 au hasard:
J'obtiens 2048 octets de 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 générée par votre machine entre les invocations de
dd if=/dev/random ...
la source
dd if=/dev/random bs=1K count=2
s'arrête lorsque la piscine d'entropie est apparemment vidé. À partir des documents, il devrait se bloquer jusqu'à ce qu'il y ait plus d'entropie, de sortedd
que le fichier sera écrit lentement, au lieu de simplement vider le pool actuel et de quitter.read(fd, mybuf, 1024)
un FD bloquant, il revient dès que l'appareil sous-jacent renvoie des données. S'il y a 1024 octets à lire, il retourne cela. S'il n'y a que 201 octets, il retournera 201. S'il n'y a aucun octet disponible, il se bloquera jusqu'à ce qu'au moins un octet devienne disponible, puis le / les retournera.Pourquoi
dd
supprime- t-il des données? ... Gilles a posé cette question intéressante à propos dedd
:Quand dd convient-il pour copier des données? (ou, quand sont read () et write () partial)
Voici un extrait de cette question:
* ... ce 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 en dessous de 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 = 8Dé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, il a fallu 2 heures 12 minutes pour collecter seulement 1192 octets, moment auquel je l'ai annulé.
Puis, me déplaçant la souris continue, il a fallu relativement beaucoup moins 1 minute 15 secondes pour recueillir le même nombre d'octets.
Cela montre assez clairement que la collecte de l' entropie n'est pas la vitesse du processeur en fonction, mais il est des événements aléatoires sur la base, et que mon système Ubuntu utilise la souris comme l' un de ses importants facteurs aléatoires.
la source
dd
est conçu pour le blocage - c'est généralement le meilleur outil à votre disposition pour lire à partir d'entrées de taille variable si vous en avez besoin immédiatement cardd
il ne tamponnera pas les lectures en cours dans un futur futurwrite()
(sauf si vous le configurez de manière très explicite de cette façon avec des obs plus grandes que ibs) , mais va à la placewrite()
tout ce qu'il lit dès qu'ilread()
est (et éventuellement le traite) .Voici quelques définitions importantes :
ibs=
expr
expr
obs=
expr
expr
bs=
expr
expr
octets, remplaçantibs=
etobs=
. Si aucune conversion autre quesync
,noerror
etnotrunc
n'est spécifiée, chaque bloc d'entrée doit être copié dans la sortie en tant que bloc unique sans agréger les blocs courts.Donc, vous voyez, quand
ibs
etobs
sont définis ensemble,bs
alorsibs
prioritaire - mais sinon, si vous êtes spécifique, alors soitobs
ou lecbs
fait.Voici un exemple dans lequel
ibs
est le plus important. Vous pourriez faire quelque chose comme ça si vous vouliez suivre la vitesse à laquelle la/dev/random
piscine s'est remplie ...Tant que
if=
la cible de 'est lisible, cela se traduira toujours par le même fichier de sortie de taille, cardd
lessync
blocs seront lus sur les valeurs nulles. En d'autres termes, sidd
read()
s pour un bloc d'entrée de$((size=10))
$((count=5))
temps et que leread()
fichier renvoie 2 octets, puis 8 octets, puis 12 octets, puis 2 octets, puis 4 octets,dd
écrira dans son fichier de sortie quelque chose comme... car
dd
, par défaut, ne tarde pas . Donc, si vous avez besoin de suivre en continu et de délimiter les écritures d'un autre processus,dd
l'outil est pour vous.Si vous écrivez simplement une certaine quantité de données dans un fichier normal, contrairement à d'autres déclarations faites ici, vous pouvez également l'utiliser
dd
pour cela - et assez facilement - mais vous en aurez besoin de plusieurs et d'un facteur de blocage fiable .Par exemple, si vous l'avez fait:
... le premier
dd
tamponnerait autant deibs="$size"
blocs d'entrée que nécessaire pour remplir au moins unobs="${size}x$block_factor"
bloc de sortie pour chacunwrite()
du tuyau entre celui-ci et le seconddd
. Cela signifie que le seconddd
peut limiter la sortie de manière fiable aveccount="$lmt"
car tous leswrite()
s que le premier fait correspondront à sa taille de bloc d'E / S - quel que soit le nombre deread()
s que le premierdd
doit faire pour le faire.Et c'est ainsi que vous pouvez utiliser
dd
pour lire de manière fiable des tuyaux ou d'autres types de fichiers spéciaux - avec juste un peu de calcul.la source