Ich führe den folgenden Befehl auf einem Ubuntu-System aus:
dd if=/dev/random of=rand bs=1K count=2
Bei jeder Ausführung erhalte ich jedoch eine Datei mit einer anderen Größe. Warum ist das? Wie kann ich eine Datei einer bestimmten Größe erzeugen, die mit zufälligen Daten gefüllt ist?
/dev/random
wird blockiert, wenn nicht genügend Entropie zur Verfügung steht, um die gewünschte Anzahl von Ziffern zu generieren. Es braucht einfach Zeit, um die Menge der zufälligen "Zufälligkeit" von Pseudoqualität zu erfassen ... Verwenden Sie entweder/dev/urandom
einen weniger zufälligen "Zufall" -Wert oder überprüfen Sie Ihren Entropiepool (in einer Schleife und warten Sie nach Bedarf) ...iflag=fullblock
Antworten:
Sie beobachten eine Kombination des besonderen Verhaltens von
dd
mit dem besonderen Verhalten von Linux/dev/random
. Beide sind im Übrigen selten das richtige Werkzeug für den Job.Linux
/dev/random
gibt Daten sparsam zurück. Es wird davon ausgegangen, dass die Entropie im Pseudozufallszahlengenerator sehr schnell erlischt. Da das Sammeln neuer Entropie langsam ist, werden in der/dev/random
Regel nur wenige Bytes gleichzeitig freigegeben.dd
ist ein altes, launisches Programm, das ursprünglich für Bandgeräte gedacht war. Wenn Sie ihm anweisen, einen Block von 1 KB zu lesen, wird versucht, einen Block zu lesen. Wenn der Lesevorgang weniger als 1024 Bytes zurückgibt, ist das alles, was Sie bekommen. Alsodd if=/dev/random bs=1K count=2
macht zweiread(2)
Anrufe. Da von dort gelesen wird/dev/random
, geben die beidenread
Aufrufe in der Regel nur wenige Bytes zurück, und zwar in unterschiedlicher Anzahl, abhängig von der verfügbaren Entropie. Siehe auch Wann eignet sich dd zum Kopieren von Daten? (oder wenn read () und write () partiell sind)Sofern Sie kein Betriebssystem-Installationsprogramm oder -Kloner entwerfen, sollten Sie es niemals
/dev/random
unter Linux verwenden/dev/urandom
. Dieurandom
Manpage ist etwas irreführend;/dev/urandom
ist in der Tat für die Kryptographie geeignet, auch um langlebige Schlüssel zu generieren. Die einzige Einschränkung dabei/dev/urandom
ist, dass es mit ausreichender Entropie versorgt werden muss; Linux-Distributionen speichern normalerweise die Entropie zwischen Neustarts, sodass Sie möglicherweise nur bei einer Neuinstallation nicht genügend Entropie haben. Entropie nutzt sich praktisch nicht ab. Weitere Informationen finden Sie unter Ist ein Rand aus / dev / urandom für einen Anmeldeschlüssel sicher? und Feeding / dev / random Entropy Pool? .Die meisten Verwendungen von
dd
werden besser mit Werkzeugen wiehead
oder ausgedrückttail
. Wenn Sie 2 KB zufällige Bytes möchten, führen Sie ausMit älteren Linux-Kerneln könnten Sie davonkommen
weil
/dev/urandom
glücklich so viele Bytes wie angefordert zurückgegeben. Dies ist jedoch nicht mehr der Fall, da Kernel 3.16 auf 32 MB beschränkt ist .Im Allgemeinen, wenn Sie verwenden müssen ,
dd
eine feste Anzahl von Bytes und seine Eingabe kommt nicht von einer normalen Datei oder Block - Gerät zu extrahieren, müssen Sie Byte für Byte lesen:dd bs=1 count=2048
.quelle
/dev/urandom
liefert 32m perread()
.dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
Ab
man 4 random
einer RHEL 5 Box:Ich erhalte Dateien mit einer Größe von 213 Bytes auf diesem Computer. Zurück zu Mann 4 zufällig:
Ich erhalte 2048 Bytes von jedem Aufruf von
dd if=/dev/urandom of=rand bs=1K count=2
Ich schließe daraus, dass der Unterschied darauf zurückzuführen ist, wie viel Entropie Ihre Maschine zwischen den Aufrufen von erzeugt
dd if=/dev/random ...
quelle
dd if=/dev/random bs=1K count=2
aufhört, wenn der Entropiepool anscheinend leer ist. In den Dokumenten sollte es blockieren, bis mehr Entropie vorhanden ist, sodass diedd
Datei langsam geschrieben wird, anstatt nur den aktuellen Pool zu löschen und zu beenden.read(fd, mybuf, 1024)
auf einer Blockierung FD gibt es, sobald das zugrunde liegende Gerät gibt einige Daten. Wenn dort 1024 Bytes gelesen werden müssen, wird dies zurückgegeben. Wenn es nur 201 Bytes gibt, wird 201 zurückgegeben. Wenn 0 Bytes verfügbar sind, wird blockiert, bis mindestens ein Byte verfügbar ist, und dann wird es / sie zurückgegeben.Warum werden
dd
Daten gelöscht? ... Gilles hat diese spannende Frage gestelltdd
:Wann ist dd zum Kopieren von Daten geeignet? (oder, wenn read () und write () partiell sind)
Hier ist ein Auszug aus dieser Frage:
* ... es ist nicht schwer, dd zu beschuldigen; Versuchen Sie zum Beispiel diesen Code: **
yes | dd of=out bs=1024k count=10
und überprüfen Sie die Größe der Ausgangsdatei (wahrscheinlich liegt sie weit unter 10 MB).
Abgesehen von meinem Kommentar (am Ende Ihrer Frage) ist so etwas interessant zu beobachten ... Es fängt Ihre Bytes in der Datei ab
$trnd
. Ich habe halb willkürlich bs = 8 gewähltBewegen Sie die Maus und beobachten Sie, wie sie schneller wird.
Mit meinem Computer im Leerlauf (AFK und keine Netzwerkaktivität) und nachdem der Entropiepool erschöpft war, dauerte es 2 Stunden und 12 Minuten , um nur 1192 Bytes zu sammeln. Zu diesem Zeitpunkt habe ich ihn abgebrochen.
Wenn ich dann die Maus ununterbrochen bewegte, dauerte es relativ viel weniger als 1 Minute und 15 Sekunden , um die gleiche Anzahl von Bytes zu sammeln.
Dies zeigt ziemlich deutlich, dass das Sammeln von Entropie nicht auf der CPU-Geschwindigkeit basiert, sondern auf zufälligen Ereignissen , und dass mein Ubuntu-System die Maus als einen seiner signifikanten Zufallsfaktoren verwendet.
quelle
dd
ist konzipiert für das Blockieren - in der Regel das beste Werkzeug zur Verfügung , es zum Lesen von variabler Größe Eingaben ist , wenn Sie es getan müssen sofort dadd
nicht aktuelle Puffer liest in eine Zukunftwrite()
(wenn Sie sehr explizit mit größeren obs als ibs es so konfigurieren) , sondernwrite()
alles, was es liest, sobald esread()
ist (und optional verarbeitet) .Hier sind einige wichtige Definitionen :
ibs=
expr
expr
obs=
expr
expr
bs=
expr
expr
Bytes ein und ersetzen Sieibs=
undobs=
. Wenn keine andere Konvertierung alssync
,noerror
undnotrunc
angegeben ist, wird jeder Eingabeblock als einzelner Block in die Ausgabe kopiert, ohne kurze Blöcke zu aggregieren.Sie sehen also, wann
ibs
undobs
wiebs
dann gemeinsam definiert werden,ibs
aber ansonsten, wenn Sie spezifisch sind, entwederobs
odercbs
.Hier ist ein Beispiel, das
ibs
am wichtigsten ist. Sie könnten so etwas tun, wenn Sie nachverfolgen möchten, wie schnell sich der/dev/random
Pool gefüllt hat ...Solange
if=
das Ziel überhaupt lesbar ist, führt dies immer zu einer Ausgabedatei mit derselben Größe, dadd
dassync
Einlesen von Blöcken auf Nullen verzögert wird. Mit anderen Worten, wenndd
read()
s für einen Eingabeblock von$((size=10))
$((count=5))
Zeiten ist und dieread()
Datei 2 Bytes zurückgibt, danndd
schreiben 8 Bytes, dann 12 Bytes, dann 2 Bytes, dann 4 Bytes in ihre Outfile wie... weil
dd
standardmäßig nicht verzögert. Wenn Sie also In-Streams verfolgen und die Schreibvorgänge eines anderen Prozesses eingrenzen müssen,dd
ist dies das richtige Werkzeug für Sie.Wenn Sie nur eine gewisse Menge an Daten in eine reguläre Datei zu schreiben dann, im Gegensatz zu anderen Aussagen hier, können Sie auch
dd
für diese - und ziemlich leicht - aber Sie brauchen mehr als einen und einen zuverlässigen Sperrfaktor .Wenn Sie zum Beispiel Folgendes getan haben:
... würde der erste
dd
so vieleibs="$size"
Eingabeblöcke puffern, wie nötig sind, um mindestens einenobs="${size}x$block_factor"
Ausgabeblock für jedenwrite()
zu der Pipe zwischen ihm und dem zweiten zu füllendd
. Dies bedeutet, dass der zweitedd
die Ausgabe zuverlässig begrenzen kann,count="$lmt"
da allewrite()
s des ersten Herstellers der E / A-Blockgröße entsprechen - unabhängig davon, wie vieleread()
s der erste dafürdd
tun muss.Auf diese Weise können Sie
dd
Pipes oder andere Arten von Spezialdateien zuverlässig lesen - mit nur ein wenig Mathematik.quelle