2009-09-22 27 views
20

¿Por qué tardó 5 minutos en generar un archivo 1 KiB en mi sistema portátil (de gama baja) con poca carga? ¿Y cómo podría generar un archivo binario aleatorio más rápido?Generando un archivo binario aleatorio

$ 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 
$ 

Observe que dd if=/dev/random of=random-file bs=1024 count=1 no funciona. Genera un archivo binario aleatorio de longitud aleatoria, en la mayoría de las ejecuciones menores de 50 B. ¿Alguien tiene una explicación para esto también?

+0

Fue difícil elegir una respuesta aceptada ya que ambas son correctas y publicadas durante el mismo minuto. Elegí la que tenía más votos, desearía poder elegir ambas. –

Respuesta

26

Esto se debe a que en la mayoría de los sistemas /dev/random utiliza datos aleatorios del entorno, como la estática de dispositivos periféricos. El conjunto de datos verdaderamente aleatorios (entropía) que utiliza es muy limitado. Hasta que haya más datos disponibles, bloques de salida.

Vuelva a intentar la prueba con /dev/urandom (observe u), y verá una aceleración significativa.

Consulte Wikipedia para obtener más información. /dev/random no siempre produce datos verdaderamente aleatorios, pero claramente lo hace en su sistema.

Ejemplo 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

Trate /dev/urandom lugar:

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

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

La diferencia principal entre el azar y urandom es la forma en que están tirando de datos aleatorios a partir del núcleo. random siempre toma datos del pool de entropía. Si el grupo está vacío, al azar bloqueará la operación hasta que el grupo se llene lo suficiente. urandom generará los datos utilizando el algoritmo SHA (o cualquier otro algoritmo, MD5 algunas veces) en el caso en que el grupo de entropía del kernel esté vacío. urandom nunca bloqueará la operación.

3

me escribió un script para probar diferentes velocidades de funciones hash. Para esto, quería archivos de datos "aleatorios", y no quería usar el mismo archivo dos veces para que ninguna de las funciones tuviera una ventaja de memoria caché del núcleo sobre la otra. Descubrí que/dev/random y/dev/urandom eran dolorosamente lentos. Elegí usar dd para copiar datos de mi disco duro comenzando en desplazamientos aleatorios. NUNCA recomendaría usar esto si estás haciendo algo relacionado con la seguridad, pero si todo lo que necesitas es ruido, no importa dónde lo obtengas. En un Mac usar algo como/dev/disco0 en Linux utilice/dev/sda

Aquí está el script de prueba completa:

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 

Aquí está el resultado "menos lentos"/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 

Éstos son los "lentos" resultados/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 

Aquí es decir son los resultados "más lentos"/dev/random:

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 

Notarás que/dev/random y/dev/urandom no fueron muy diferentes en velocidad. Sin embargo,/dev/disk0 tomó la mitad del tiempo.

PS.Disminuyo el número de pruebas y eliminé todas las órdenes excepto 2 por el bien de "brevedad" (no es que haya tenido éxito en ser breve).

0

Tema viejo pero necesitaba lo mismo. El viejo amigo C vino a rescatarme porque no quiero meterme con guiones. Aquí está mi solución que es bueno y lo suficientemente rápido para mí:

// 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

hilo viejo, pero como se mencionó Tobbe, necesitaba algo como esto sólo es mejor (más rápido).

Así que ... una forma de caparazón de hacerlo de la misma manera, más rápida que aleatoria/urandom, útil cuando se crean archivos realmente grandes, admito que no completamente al azar, pero lo suficientemente cerca probablemente, depende de sus necesidades.

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

Esto creará un archivo de 100 Gb a partir del contenido de la memoria RAM (la primera de 1 GB, que se supone que tiene tanta memoria RAM :)) Tenga en cuenta que también es probablemente seguro para compartir este archivo, ya que puede contener toda tipos de datos confidenciales como sus contraseñas, así que úselas solo por sus propias causas :) Ah, y necesita ejecutarlo como root por la misma razón.