Estoy ejecutando el siguiente comando en un sistema ubuntu:
dd if=/dev/random of=rand bs=1K count=2
Sin embargo, cada vez que lo ejecuto, termino con un archivo de un tamaño diferente. ¿Por qué es esto? ¿Cómo puedo generar un archivo de un tamaño determinado lleno de datos aleatorios?

/dev/randomse bloqueará si no hay suficiente entropía disponible para generar la cantidad de dígitos que desea. simplemente toma tiempo reunir esa cantidad de "aleatoriedad" aleatoria de psuedo de alta calidad ... O use/dev/urandompara un valor "aleatorio" menos aleatorio, o verifique su grupo de entropía (en un bucle, y espere según sea necesario) ...iflag=fullblockRespuestas:
Estás observando una combinación del comportamiento peculiar de
ddcon el comportamiento peculiar de Linux/dev/random. Ambos, por cierto, rara vez son la herramienta adecuada para el trabajo.Linux
/dev/randomdevuelve datos con moderación. Se basa en el supuesto de que la entropía en el generador de números pseudoaleatorios se extingue a una velocidad muy rápida. Dado que la recopilación de nueva entropía es lenta,/dev/randomgeneralmente solo se renuncian unos pocos bytes por vez.ddes un programa viejo y malhumorado destinado inicialmente a funcionar en dispositivos de cinta. Cuando le dice que lea un bloque de 1kB, intenta leer un bloque. Si la lectura devuelve menos de 1024 bytes, difícil, eso es todo lo que obtienes. Entoncesdd if=/dev/random bs=1K count=2hace dosread(2)llamadas. Como está leyendo/dev/random, las dosreadllamadas generalmente devuelven solo unos pocos bytes, en número variable dependiendo de la entropía disponible. Consulte también ¿ Cuándo es adecuado dd para copiar datos? (o, cuando se leen () y escriben () parcial)A menos que esté diseñando un instalador o clonador del sistema operativo, nunca debe usarlo
/dev/randombajo Linux, siempre/dev/urandom. Laurandompágina del manual es algo engañosa;/dev/urandomDe hecho, es adecuado para la criptografía, incluso para generar claves de larga duración. La única restricción con/dev/urandomes que debe suministrarse con suficiente entropía; Las distribuciones de Linux normalmente guardan la entropía entre reinicios, por lo que el único momento en que podría no tener suficiente entropía es en una instalación nueva. La entropía no desaparece en términos prácticos. Para obtener más información, lea ¿Es seguro un rand de / dev / urandom para una clave de inicio de sesión? y el grupo de alimentación / dev / entropía aleatoria? .La mayoría de los usos de
ddse expresan mejor con herramientas comoheadotail. Si quieres 2kB de bytes aleatorios, ejecutaCon los núcleos de Linux más antiguos, podría salirse con la suya
porque
/dev/urandomfelizmente devolvió tantos bytes como se solicitó. Pero esto ya no es cierto desde el kernel 3.16, ahora está limitado a 32 MB .En general, cuando se necesita para el uso
ddpara extraer un número fijo de bytes y su entrada no proviene de un archivo normal o dispositivo de bloque, es necesario leer byte a byte:dd bs=1 count=2048.fuente
/dev/urandomdevuelve 32m porread().dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2Desde
man 4 randomuna caja RHEL 5:Recibo archivos de 213 bytes en esa máquina. De vuelta al hombre 4 al azar:
Obtengo 2048 bytes de cada invocación de
dd if=/dev/urandom of=rand bs=1K count=2Concluyo que la diferencia se debe a la cantidad de entropía que genera su máquina entre invocaciones de
dd if=/dev/random ...fuente
dd if=/dev/random bs=1K count=2detiene cuando el grupo de entropía aparentemente está drenado. Desde los documentos, debe bloquearse hasta que haya más entropía, por loddque escribirá el archivo lentamente, en lugar de simplemente eliminar el grupo actual y salir.read(fd, mybuf, 1024)a un FD de bloqueo, vuelve tan pronto como el dispositivo subyacente devuelve algunos datos. Si hay 1024 bytes para ser leídos, devuelve eso. Si solo hay 201 bytes, devolverá 201. Si hay 0 bytes disponibles, se bloqueará hasta que al menos un byte esté disponible, luego lo devolverá.¿Por qué se
ddcaen los datos? ... Gilles ha planteado esta interesante pregunta sobredd: ¿Cuándo es adecuado dd para copiar datos? (o, cuando se lee () y escribe () parcial)
Aquí hay un extracto de esa pregunta:
* ... no es difícil culpar a dd; por ejemplo, pruebe este código: **
yes | dd of=out bs=1024k count=10y verifique el tamaño del archivo de salida (es probable que sea muy inferior a 10 MB).
Aparte de mi comentario (al final de su pregunta), algo como esto es interesante de ver ... Captura sus bytes en el archivo
$trnd. He elegido semi-arbitrariamente bs = 8Mueve el mouse y observa cómo se acelera.
Con mi computadora inactiva (AFK y sin actividad de red), y después de agotar el grupo de entropía, me tomó 2 horas 12 minutos recolectar solo 1192 bytes, momento en el cual lo cancelé.
Luego, al mover el mouse continuamente, me tomó un tiempo relativamente más corto de 1 minuto y 15 segundos para recopilar la misma cantidad de bytes.
Esto muestra con bastante claridad que la recopilación de entropía no se basa en la velocidad de la CPU, sino que se basa en eventos aleatorios , y que mi sistema Ubuntu usa el mouse como uno de sus factores aleatorios significativos .
fuente
ddestá diseñado para bloquear: por lo general, es la mejor herramienta a su disposición para leer desde entradas de tamaño variable si lo necesita de inmediato, yaddque no almacenará las lecturas de corriente en el futurowrite()(a menos que lo configure de manera muy explícita de esa manera con un obs mayor que ibs) , pero, en cambiowrite(), leerá todo lo que lea tan pronto comoread()sea (y opcionalmente lo procesará) .Aquí hay algunas definiciones importantes :
ibs=exprexprobs=exprexprbs=exprexprbytes, reemplazandoibs=yobs=. Si no se especifica otra conversión quesync,noerrorynotruncse especifica, cada bloque de entrada se copiará a la salida como un bloque único sin agregar bloques cortos.Así que ya ves, cuándo
ibsyobsse definen juntos comobsentoncesibstiene prioridad, pero de lo contrario, si eres específico, entoncesobso locbshace.Aquí hay un ejemplo en el que
ibses más importante. Puede hacer algo como esto si desea realizar un seguimiento de lo pronto que se/dev/randomllenó la piscina ...Mientras
if='s objetivo se puede leer en absoluto, que será siempre como resultado el mismo tamaño de archivo de salida, porqueddsesynchronize bloques de lectura en el nulos. En otras palabras, siddread()s es para un bloque de entrada de$((size=10))$((count=5))tiempos y elread()archivo devuelve 2 bytes, luego 8 bytes, luego 12 bytes, luego 2 bytes, luego 4 bytes,ddescribirán en su archivo de salida algo como... porque
dd, por defecto, no se retrasa. Entonces, si necesita realizar un seguimiento in-stream y delimitar las escrituras de algún otro proceso, estaddes la herramienta para usted.Si solo está escribiendo cierta cantidad de datos en un archivo normal, a diferencia de otras declaraciones hechas aquí, también puede usarlo
ddpara esto, y con bastante facilidad, pero necesitará más de uno y un factor de bloqueo confiable .Por ejemplo, si hiciste:
... el primero
ddalmacenará tantosibs="$size"bloques de entrada como sean necesarios para llenar al menos unobs="${size}x$block_factor"bloque de salida por cadawrite()tubería entre él y el segundodd. Esto significa que el segundoddpuede limitar la salida de manera confiablecount="$lmt"porque todos loswrite()s que realiza el primero coincidirán con su tamaño de bloque de E / S, independientemente de cuántosread()sdddebe hacer el primero para hacerlo.Y así es como puede usar
ddpara leer de manera confiable tuberías u otros tipos de archivos especiales, con solo un poco de matemática.fuente