2009-09-22 14 views
20

Perché sono stati necessari 5 minuti per generare un file 1 KiB sul mio sistema (laptop di fascia bassa) con un carico ridotto? E come posso generare un file binario casuale più veloce?Generazione di un file binario casuale

$ time dd if=/dev/random of=random-file bs=1 count=1024 
1024+0 records in 
1024+0 records out 
1024 bytes (1.0 kB) copied, 303.266 s, 0.0 kB/s 

real 5m3.282s 
user 0m0.000s 
sys 0m0.004s 
$ 

Si noti che dd if=/dev/random of=random-file bs=1024 count=1 non funziona. Genera un file binario casuale di lunghezza casuale, sulla maggior parte delle esecuzioni sotto i 50 B. Qualcuno ha una spiegazione anche per questo?

+0

È stato difficile scegliere una risposta accettata poiché entrambi sono corretti e pubblicati nello stesso minuto. Ho scelto quello con più voti, vorrei poter scegliere entrambi. –

risposta

26

Questo perché sulla maggior parte dei sistemi /dev/random utilizza dati casuali provenienti dall'ambiente, come quelli statici dai dispositivi periferici. Il pool di dati veramente casuali (entropia) che utilizza è molto limitato. Fino a quando non saranno disponibili più dati, i blocchi di output.

Riprova il test con /dev/urandom (noti lo u) e vedrai una significativa accelerazione.

Vedere Wikipedia per ulteriori informazioni. /dev/random non genera sempre dati veramente casuali, ma chiaramente sul tuo sistema.

Esempio con /dev/urandom:

$ time dd if=/dev/urandom of=/dev/null bs=1 count=1024 
1024+0 records in 
1024+0 records out 
1024 bytes (1.0 kB) copied, 0.00675739 s, 152 kB/s 

real 0m0.011s 
user 0m0.000s 
sys 0m0.012s 
12

Prova /dev/urandom invece:

$ time dd if=/dev/urandom of=random-file bs=1 count=1024 

Da: http://stupefydeveloper.blogspot.com/2007/12/random-vs-urandom.html

La differenza principale tra casuale e urandom è il modo in cui stanno tirando i dati casuali da kernel. random prende sempre i dati dal pool di entropia. Se il pool è vuoto, random bloccherà l'operazione fino a quando il pool non verrà riempito abbastanza. urandom genera i dati utilizzando l'algoritmo SHA (o qualsiasi altro algoritmo, a volte MD5) nel caso in cui il pool entropy del kernel sia vuoto. urandom non bloccherà mai l'operazione.

3

Ho scritto uno script per testare diverse velocità funzioni di hashing. Per questo volevo file di dati "casuali" e non volevo utilizzare lo stesso file due volte in modo che nessuna delle funzioni avesse un vantaggio della cache del kernel rispetto all'altra. Ho scoperto che sia/dev/random che/dev/urandom erano dolorosamente lenti. Ho scelto di usare dd per copiare i dati del mio hard disk a partire da offset casuali. Non consiglierei MAI di usarlo se stai facendo qualcosa di relativo alla sicurezza, ma se tutto ciò di cui hai bisogno è rumore, non importa dove lo ottieni. Su un Mac usare qualcosa come/dev/disk0 su Linux uso/dev/sda

Ecco lo script di test completo:

tests=3 
kilobytes=102400 
commands=(md5 shasum) 
count=0 
test_num=0 
time_file=/tmp/time.out 
file_base=/tmp/rand 

while [[ test_num -lt tests ]]; do 
    ((test_num++)) 
    for cmd in "${commands[@]}"; do 
     ((count++)) 
     file=$file_base$count 
     touch $file 
     # slowest 
     #/usr/bin/time dd if=/dev/random of=$file bs=1024 count=$kilobytes >/dev/null 2>$time_file 
     # slow 
     #/usr/bin/time dd if=/dev/urandom of=$file bs=1024 count=$kilobytes >/dev/null 2>$time_file                           
     # less slow 
     /usr/bin/time sudo dd if=/dev/disk0 skip=$(($RANDOM*4096)) of=$file bs=1024 count=$kilobytes >/dev/null 2>$time_file 
     echo "dd took $(tail -n1 $time_file | awk '{print $1}') seconds" 
     echo -n "$(printf "%7s" $cmd)ing $file: " 
     /usr/bin/time $cmd $file >/dev/null 
     rm $file 
    done 
done 

Qui è il "meno lenti" risultati/dev/disk0:

dd took 6.49 seconds 
    md5ing /tmp/rand1:   0.45 real   0.29 user   0.15 sys 
dd took 7.42 seconds 
shasuming /tmp/rand2:   0.93 real   0.48 user   0.10 sys 
dd took 6.82 seconds 
    md5ing /tmp/rand3:   0.45 real   0.29 user   0.15 sys 
dd took 7.05 seconds 
shasuming /tmp/rand4:   0.93 real   0.48 user   0.10 sys 
dd took 6.53 seconds 
    md5ing /tmp/rand5:   0.45 real   0.29 user   0.15 sys 
dd took 7.70 seconds 
shasuming /tmp/rand6:   0.92 real   0.49 user   0.10 sys 

Qui ci sono le "lenti" risultati/dev/urandom:

dd took 12.80 seconds 
    md5ing /tmp/rand1:   0.45 real   0.29 user   0.15 sys 
dd took 13.00 seconds 
shasuming /tmp/rand2:   0.58 real   0.48 user   0.09 sys 
dd took 12.86 seconds 
    md5ing /tmp/rand3:   0.45 real   0.29 user   0.15 sys 
dd took 13.18 seconds 
shasuming /tmp/rand4:   0.59 real   0.48 user   0.10 sys 
dd took 12.87 seconds 
    md5ing /tmp/rand5:   0.45 real   0.29 user   0.15 sys 
dd took 13.47 seconds 
shasuming /tmp/rand6:   0.58 real   0.48 user   0.09 sys 

Ecco sono i "più lenti"/dev/risultati casuali:

dd took 13.07 seconds 
    md5ing /tmp/rand1:   0.47 real   0.29 user   0.15 sys 
dd took 13.03 seconds 
shasuming /tmp/rand2:   0.70 real   0.49 user   0.10 sys 
dd took 13.12 seconds 
    md5ing /tmp/rand3:   0.47 real   0.29 user   0.15 sys 
dd took 13.19 seconds 
shasuming /tmp/rand4:   0.59 real   0.48 user   0.10 sys 
dd took 12.96 seconds 
    md5ing /tmp/rand5:   0.45 real   0.29 user   0.15 sys 
dd took 12.84 seconds 
shasuming /tmp/rand6:   0.59 real   0.48 user   0.09 sys 

Si noterà che/dev/random e/dev/urandom non erano molto diversi nella velocità. Tuttavia,/dev/disk0 ha impiegato 1/2 tempo.

PS.Riduco il numero di test e rimossi tutti tranne 2 comandi per motivi di "brevità" (non che io sia riuscito a essere breve).

0

Vecchio thread ma ho solo bisogno della stessa cosa. Il vecchio amico C è venuto in soccorso poiché non voglio scherzare con gli script. Ecco la mia soluzione, che è buono e abbastanza veloce per me:

// usage: ./program <outfile> <size-in-bytes> 
#include <stdio.h> 
void main(int argc, char** argv){ 
    long long i, s; 
    FILE* f = fopen(*(argv+1), "w"); 
    srand(time(NULL)); 
    sscanf(*(argv+2), "%lld", &s); 
    for(i=0;i<s;i++){ 
     fputc(rand()%255,f); 
    } 
    fclose(f); 
} 
2

thread vecchio, ma come Tobbe detto, ho bisogno di qualcosa di simile solo meglio (più veloce).

Quindi ... un modo guscio di farlo lo stesso, solo in modo più rapido allora casuale/urandom, utile quando si creano file di grandi dimensioni, non ammettere completamente casuale, ma abbastanza vicino, probabilmente, dipende dalle vostre esigenze.

dd if=/dev/mem of=test1G.bin bs=1M count=1024 
touch test100G.bin 
seq 1 100 | xargs -Inone cat test1G.bin >> test100G.bin 

Questo creerà un file di 100Gb dal contenuto della RAM (il primo da 1 GB, suppongo che voi avete così tanto ram :)) Si noti che è anche probabilmente non sicuri di condividere questo file in quanto può contenere tutte tipi di dati sensibili come le tue password, quindi usali solo per le tue cause :) Oh, e devi eseguirlo come root per lo stesso motivo.