sonnenblen.de - Das unabhängige Sun User Forum
Betriebssysteme => Solaris => Thema gestartet von: escimo am 31. Januar 2008, 12:22:39
-
Hallo zusammen,
ich habe gerade ein "Hänger" mit dem Kommando /usr/bin/dd.
Hintergrund: ich möchte eine aus zufällig generierten (Binär-)Daten bestehende Datei, die eine feste Größe im Dateisystem aufweist, um es als Anhang mittels dem Kommando mailx an eine beliebige Adresse zu versenden.
Dabei habe ich die Auswahl zwischen folgenden "if"-Optionen (input files):
- /dev/random -> ../devices/pseudo/random@0:random
- /dev/urandom -> ../devices/pseudo/random@0:urandom
- /dev/zero -> ../devices/pseudo/mm@0:zero
Nun mit folgenden Kommando kann ich dann eine Datei fester Größe generieren:
$> dd bs=512 count=2 if=/dev/zero of=zerofile
2+0 records in
2+0 records out
$> ls -l zerofile
-rw-r--r-- 1 sschaars staff 1024 Jan 31 11:57 zerofile
$> dd bs=8b count=2 if=/dev/zero of=zerofile
2+0 records in
2+0 records out
$> ls -l zerofile
-rw-r--r-- 1 sschaars staff 8192 Jan 31 11:58 zerofile
Gut die Datei (Größe="2+0" Blöcke) hat die gewünschten Größen (8b=8x512byte Blöcke) aber enthält natürlich keinerlei zufällig generierte Daten.
Nun dachte ich mir, mit /dev/(u)random müsste sich die Erzeugung einer Binärdatei fester Größer doch bewerkstelligen lassen:
$> dd bs=512 count=2 if=/dev/random of=randomfile
0+2 records in
0+2 records out
$> ls -l randomfile
-rw-r--r-- 1 sschaars staff 170 Jan 31 12:10 randomfile
$> dd bs=8b count=2 if=/dev/random of=randomfile
0+2 records in
0+2 records out
$> ls -l randomfile
-rw-r--r-- 1 sschaars staff 2080 Jan 31 12:11 randomfile
170 Bytes? ??? Ich habe hier 1024 Byte erwartet. Was habe ich nicht beachtet?
Grüße
escimo
EDIT: Ich lese mir nochmal die Manpages dazu durch:
$> man -s 7d random
-
Habs grad eben versucht (auf Solaris 10 SPARC), sowohl bei /dev/random als auch bei /dev/urandom stimmt die Groesse bei mir genau...
-
Ich konnte Dein Problem hier nicht reproduzieren.
$ uname -rsv
SunOS 5.8 Generic_108528-22
$ dd bs=512 count=2 if=/dev/random of=randomfile
2+0 records in
2+0 records out
$ ls -l randomfile
-rw-r--r-- 1 edi edi 1024 Jan 31 12:34 randomfile
Apropos manpage, da war mir folgendes aufgefallen:
If there is no entropy to produce the requested number of
bytes, /dev/random blocks until more entropy can be
obtained.
Du hast ja zwei unvollständige Leseoperationen bekommen (0+2 records), also jeweils weniger als die erwarteten 512 Byte. dd macht also offenbar ein non-blocking read und wenn /dev/random sagt ich hab nichts mehr dann ist Schluss.
Keine Ahnung wie man am besten mehr Entropy erzeugt - wahrscheinlich muss auf der Kiste einfach nur genug los sein. Vielleicht vorher einfach einen fiesen Job im Hintergrund starten. ;D
-
Aha,
vielen Dank für die Infos. Das habe ich in der Manpage zu /dev/random wohl überlesen. ;)
Mmm ... ich habe jeweils ein Kommando vor kurzem noch einmal auf den Servern (Linux/x86 und Solaris/SPARC) abgesetzt. Jetzt stimmen die Dateigrößen bis auf einen Server plötzlich. Das sind eigentlich alles Server, die unter Dauerfeuer stehen. Das will wer verstehen ???
Auf dem Linux-Server reicht die erzeugte Entropy-Datenmenge dann wohl noch nicht aus:
$> dd count=2 if=/dev/random of=randomfile
0+2 records in
0+1 records out
$> ls -l randomfile
-rw-r--r-- 1 sschaars inet 191 2008-01-31 14:56 randomfile
$> uname -a
Linux xxxxxxxx 2.6.5-7.282-bigsmp #1 SMP Tue Aug 29 10:40:40 UTC 2006 i686 i686 i386 GNU/Linux
Bei der obigen Ausgabe hat dd dann wohl ein Block in der Ausgabe "verschluckt"? ;)
Auszug aus der Manpage zu "dd":
>0 An error occurred.
If an input error is detected and the noerror conversion has
not been specified, any partial output block will be written
to the output file, a diagnostic message will be written,
and the copy operation will be discontinued. If some other
error is detected, a diagnostic message will be written and
the copy operation will be discontinued.
Gruß
escimo
-
Unter Linux füllt sich die Entropy über verschiedenste Input. Wird /dev/random aber abgerufen, verringert sich die Entropy.
Zu sehen über avail_entropy im Proc-Dateisystem.
Ist diese zu gering, wird die Ausgabe gesperrt.
Im Linuxmagazin (http://linuxmagazin.de/heft_abo/ausgaben/2006/11/kern_technik?category=0) war dazu mal ein prima Artikel. Ich hab den allerdings nur in der Printausgabe vollständig.
-
Hintergrund: ich möchte eine aus zufällig generierten (Binär-)Daten bestehende Datei, die eine feste Größe im Dateisystem aufweist, um es als Anhang mittels dem Kommando mailx an eine beliebige Adresse zu versenden.
Wie wäres es mit ver Verwendung von C-Code anstatt /usr/bin/dd ?
(Gut, gebe zu, dass es nicht einfach ist, einen guten Zufallszahlengenerator zu schreiben.)
Martin
-
Unter Linux füllt sich die Entropy über verschiedenste Input. Wird /dev/random aber abgerufen, verringert sich die Entropy.
Zu sehen über avail_entropy im Proc-Dateisystem.
Ist diese zu gering, wird die Ausgabe gesperrt.
Oha, das werde ich nächste Woche mal überprüfen. Danke Toktar.
Wie wäres es mit ver Verwendung von C-Code anstatt /usr/bin/dd ?
(Gut, gebe zu, dass es nicht einfach ist, einen guten Zufallszahlengenerator zu schreiben.)
Hallo Martin, ja das wäre in der Tat eine recht anspruchsvolle und durchaus interessante Aufgabe, für die ich aber leider auf Arbeit kaum Zeit bekommen würde und privat habe ich mehr als genug "waghalsiger" und "übergewichtiger" Software-Vorhaben. ;)
Gruß
escimo
-
Hallo Martin, ja das wäre in der Tat eine recht anspruchsvolle und durchaus interessante Aufgabe, für die ich aber leider auf Arbeit kaum Zeit bekommen würde und privat habe ich mehr als genug "waghalsiger" und "übergewichtiger" Software-Vorhaben. ;)
/* File myrandom.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>
int main(int argc,char **argv)
{
unsigned char sds[]={13,17,19,23,29};
int i,j,s,v;
struct tms dummy;
if(argc>1) i=atoi(argv[1]);
while(argc<2 || i--)
{
s=s*sds[4];
v=times(&dummy);
for(j=0;j<4;j++) s+=sds[j]*(v>>(8*j));
putchar(s);
}
return 0;
}
myrandom 10000 > myfile.bin
Hat mich jetzt gerade mal 15 Minuten gekostet.
Martin
-
debian:~# cat /proc/sys/kernel/random/entropy_avail
3167
debian:~# hexdump /dev/random
..... <Strg+C>
debian:~# cat /proc/sys/kernel/random/entropy_avail
67
debian:~# hexdump /dev/random
<nu kommt nix mehr>
-
1 /* File myrandom.c */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/times.h>
5
6 int main(int argc,char **argv)
7 {
8 unsigned char sds[]={13,17,19,23,29};
9 int i,j,s,v;
10 struct tms dummy;
11 if(argc>1) i=atoi(argv[1]);
12 while(argc<2 || i--)
13 {
14 s=s*sds[4];
15 v=times(&dummy);
16 for(j=0;j<4;j++) s+=sds[j]*(v>>(8*j));
17 putchar(s);
18 }
19 return 0;
20 }
Hat mich jetzt gerade mal 15 Minuten gekostet.
Ich hätte nicht gedacht, dass nur 20 Zeilen Quellcode nötig wären. Man merkt, ich bin mit der Materie nicht wirklich vertraut. Zu dieser Thematik muss ich mich bei Gelegenheit kundig machen. :-\
Mal sehen, ob ich das zusammenbekomme:
L1: Kommentar
L2-4: Einbindung benötigter Header
L6: Definition Funktion main()
L7: Block-Beginn Funktion main()
L8: Definition sds[]-Array für Zeichen (standard deviations of generated variables?) - in diesem Fall Steuerzeichen (numerische Bedeutung: Primzahlen)
13 = 'CR' (Carriage Return)
17 = 'DC1' (Device Control 1)
19 = 'DC3' (~ 3)
23 = 'ETB' (End of Transmission Block)
29 = 'GS' (Group Separator)
L9: Deklaration von Integer-Variablen "i", "j" (Zähler) und "s" (Symbol?) sowie "v" (Zeit vergangen?)
L10: Deklaration Struktur tms mit Namen "dummy"
L11: Parameter angegeben? Wenn ja, Umwandlung des ersten Parameters von ASCII nach Integer und Speichern mit Variable "i"
L12: Kopf der Schleife;
L13: Block-Beginn der Schleife
L14-L16: Erzeugung des zufälligen Zeichens mit Multiplikation, Addition und Right-Shifting und einer inneren Schleife (L16 ???)
L17: "s" wird auf die Standardausgabe geschrieben
L18: Block-Ende der Schleife
L19: Verlassen der Funktion main() mit Rückgabewert "0"
L20: Block-Ende Funktion main()
$> dd bs=512 count=2000 if=myrandom of=randomfile
14+1 records in
14+1 records out
$> ls -l randomfile
-rw-r--r-- 1 sx users 7416 Feb 3 17:13 randomfile
$> myrandom 1000 > randomfile2
$> ls -l randomfile2
-rw-r--r-- 1 sx users 142577 Feb 3 17:13 randomfile2
Hätte in Zeile 13 "while (i--)" nicht gereicht oder wolltest du dir den Test auf "(argc<2) ? a:b" sparen?
Was passiert auf Zeile (Line) 16 im Detail, Martin? Kannst du das dem escimo erklären? ::)
Grüße
Stephan
-
L8: Definition sds[]-Array für Zeichen (standard deviations of generated variables?) - in diesem Fall Steuerzeichen (numerische Bedeutung: Primzahlen)
L14-L16: Erzeugung des zufälligen Zeichens mit Multiplikation, Addition und Right-Shifting und einer inneren Schleife (L16 ???)
Was passiert auf Zeile (Line) 16 im Detail, Martin? Kannst du das dem escimo erklären? ::)
Hier habe ich an "SeeDS" gedacht. Hier einfach Primzahlen - die eignen sich besonders dafür. Sie sollen in Zeile 16 dafür sorgen, dass jedes Byte der Zeit aus "times()" auch irgendwie ins untere Byte von "s" hineinkommt, da sonst ja nur das untere Byte von "times()" verwendet werden würde.
Schließlich wird nur das untere Byte von "s" geschrieben; die höheren Bytes von "s" kommen niemals nach unten. Da auch die oberen Bytes von "times()" mehr oder weniger "zufällig" sind, werden sie in Zeile 16 nach unten kopiert.
$> myrandom 1000 > randomfile2
$> ls -l randomfile2
-rw-r--r-- 1 sx users 142577 Feb 3 17:13 randomfile2
Das wundert mich jetzt aber. Bei mir war die Datei genau so groß wie das Argument (also bei "myrandom 1000" war die Datei 1000 Bytes lang).
Hätte in Zeile 13 "while (i--)" nicht gereicht oder wolltest du dir den Test auf "(argc<2) ? a:b" sparen?
Das ganze funktioniert so:
Fall: Keine Argumente angegeben: argc ist 1 => Endlosschleife; eignet sich für "myrandom | dd bs=1 count=1000 > outfile"
Fall: Argumente angegeben: argc>1 => Schleife läuft i mal durch
Grüße
Martin
-
Hier habe ich an "SeeDS" gedacht. Hier einfach Primzahlen - die eignen sich besonders dafür. Sie sollen in Zeile 16 dafür sorgen, dass jedes Byte der Zeit aus "times()" auch irgendwie ins untere Byte von "s" hineinkommt, da sonst ja nur das untere Byte von "times()" verwendet werden würde.
Schließlich wird nur das untere Byte von "s" geschrieben; die höheren Bytes von "s" kommen niemals nach unten. Da auch die oberen Bytes von "times()" mehr oder weniger "zufällig" sind, werden sie in Zeile 16 nach unten kopiert.
Ich kann dir zwar "noch" nicht folgen aber mit der Zeit steige ich bestimmt dahinter. :-\
Das ganze funktioniert so:
Fall: Keine Argumente angegeben: argc ist 1 => Endlosschleife; eignet sich für "myrandom | dd bs=1 count=1000 > outfile"
Fall: Argumente angegeben: argc>1 => Schleife läuft i mal durch
Oha, in Ordnung. Das habe ich jetzt. Nächstes Wochenende Poste ich mal einen erweiterten Output dieses Programms. Vielen Dank Martin.
@Toktar: user@host:~ $ cat /proc/sys/kernel/random/entropy_avail
3712
user@host:~ $ dd bs=512 count=4 if=/dev/random of=randomfile
0+4 records in
0+4 records out
user@host:~ $ ls -l randomfile
-rw-r--r-- 1 user users 342 2008-02-04 16:12 randomfile
user@host:~ $ cat /proc/sys/kernel/random/entropy_avail
3604
Das geht wieder "was" verloren und Entropy-Informationen sollten genügend vorliegen. ???
Grüße
Stephan
-
Shell 1
simon:/home# cat /etc/debian_version
4.0
simon:/home# uname -a
Linux simon 2.6.18-4-686 #1 SMP Wed May 9 23:03:12 UTC 2007 i686 GNU/Linux
simon:/home# dd bs=512 count=4 if=/dev/random of=randomfile
0+4 Datensätze ein
0+4 Datensätze aus
93 Bytes (93 B) kopiert, 75,1021 Sekunden, 0,0 kB/s
simon:/home# ls -ltrh
-rw-r--r-- 1 root root 93 2008-02-04 18:11 randomfile
simon:/home#
Shell 2 (parallel zum dd)
simon:~# cat /proc/sys/kernel/random/entropy_avail
40
simon:~# cat /proc/sys/kernel/random/entropy_avail
40
simon:~# cat /proc/sys/kernel/random/entropy_avail
63
simon:~# cat /proc/sys/kernel/random/entropy_avail
63
simon:~# cat /proc/sys/kernel/random/entropy_avail
2
simon:~# cat /proc/sys/kernel/random/entropy_avail
72
simon:~# cat /proc/sys/kernel/random/entropy_avail
129
Die entrophy_avail erholt sich auf meiner Kiste auch nicht so schnell. Nach einer halben Stunden und Grundreinigung meiner 5jährigenTochter ist sie nun auf 450 gestiegen.
-
...Nächstes Wochenende Poste ich mal einen erweiterten Output dieses Programms.
Da gerade eine Tip-Verbindung von der SS20 zur U80 aktiv ist, habe ich die Gelegenheit genutzt, den erweiterten Output noch wie angekündigt bereitzustellen.
/* file by mdjr */
#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>
int main( int argc, char **argv )
{
unsigned char sds[] = {13,17,19,23,29};
int i, j, s, v;
struct tms dummy;
int c = 1; //counter
int sc = 0; //cache for variable 's'
if (argc>1) i = atoi( argv[1] );
while (argc<2 || i-- ) {
// while (i--) {
printf("Durchlauf %d:",c++);
s = s * sds[4];
printf(" s_davor=%d,",s);
v = times( &dummy );
printf(" v=%d,",v);
for (j=0; j<4; j++) {
s += sds[j] * (v >> (8*j));
sc = s;
printf("\n\t %d = %d + %d * (%d >> (8 * %d))",s,sc,sds[j],v,j);
}
printf("\n");
putchar(s);
if (argc<2 || i) printf("Repeat loop: true\n",i);
else printf("Repeat loop: false\n",i);
}
return 0;
}
Gruß
escimo