Saya menjalankan perintah berikut pada sistem ubuntu:
dd if=/dev/random of=rand bs=1K count=2
Namun, setiap kali saya menjalankannya, saya mendapatkan file dengan ukuran berbeda. Kenapa ini? Bagaimana saya bisa menghasilkan file dengan ukuran tertentu yang diisi dengan data acak?
/dev/random
akan memblokir jika tidak ada cukup entropi yang tersedia untuk menghasilkan jumlah digit yang Anda inginkan. hanya perlu waktu untuk mengumpulkan jumlah "acak" acak psuedo acak berkualitas tinggi ... Baik gunakan/dev/urandom
untuk nilai "acak" yang kurang acak, atau periksa kumpulan entropi Anda (dalam satu lingkaran, dan tunggu seperlunya) ...iflag=fullblock
Jawaban:
Anda mengamati kombinasi perilaku aneh
dd
dengan perilaku aneh Linux/dev/random
. Omong-omong, keduanya jarang merupakan alat yang tepat untuk pekerjaan itu.Linux
/dev/random
mengembalikan data dengan hemat. Hal ini didasarkan pada asumsi bahwa entropi pada generator nomor pseudorandom dipadamkan dengan kecepatan yang sangat cepat. Karena mengumpulkan entropi baru lambat,/dev/random
biasanya hanya melepaskan beberapa byte pada satu waktu.dd
adalah program lama yang rewel yang pada awalnya dimaksudkan untuk beroperasi pada perangkat pita. Ketika Anda menyuruhnya membaca satu blok 1kB, ia mencoba membaca satu blok. Jika pembacaan mengembalikan kurang dari 1024 byte, sulit, itu saja yang Anda dapatkan. Jadi,dd if=/dev/random bs=1K count=2
buat duaread(2)
panggilan. Karena membaca dari/dev/random
, duaread
panggilan biasanya mengembalikan hanya beberapa byte, dalam jumlah yang bervariasi tergantung pada entropi yang tersedia. Lihat juga Kapan dd cocok untuk menyalin data? (atau, ketika dibaca () dan tulis () parsial)Kecuali Anda mendesain installer atau cloner OS, Anda seharusnya tidak pernah menggunakan
/dev/random
Linux, selalu/dev/urandom
. Theurandom
halaman manual agak menyesatkan;/dev/urandom
sebenarnya cocok untuk kriptografi, bahkan untuk menghasilkan kunci berumur panjang. Satu-satunya batasan/dev/urandom
adalah bahwa ia harus dilengkapi dengan entropi yang memadai; Distribusi Linux biasanya menyimpan entropi di antara reboot, jadi satu-satunya saat Anda mungkin tidak memiliki cukup entropi adalah pada instalasi baru. Entropi tidak hilang secara praktis. Untuk informasi lebih lanjut, baca Apakah rand dari / dev / urandom aman untuk kunci masuk? dan Feeding / dev / pool entropi acak? .Sebagian besar penggunaan
dd
lebih baik diungkapkan dengan alat sepertihead
atautail
. Jika Anda ingin 2kB byte acak, jalankanDengan kernel Linux yang lebih lama, Anda bisa lolos
karena
/dev/urandom
dengan senang hati mengembalikan byte sebanyak yang diminta. Tetapi ini tidak lagi benar sejak kernel 3.16, sekarang terbatas pada 32MB .Secara umum, ketika Anda harus menggunakan
dd
untuk mengekstrak jumlah tetap byte dan input tidak datang dari sebuah file biasa atau perangkat blok, Anda perlu membaca byte dengan byte:dd bs=1 count=2048
.sumber
/dev/urandom
menghasilkan 32m perread()
.dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
Dari
man 4 random
pada kotak RHEL 5:Saya mendapatkan file ukuran 213 byte pada mesin itu. Kembali ke man 4 acak:
Saya mendapatkan 2048 byte dari setiap doa
dd if=/dev/urandom of=rand bs=1K count=2
Saya menyimpulkan bahwa perbedaannya adalah karena berapa banyak entropi yang dihasilkan mesin Anda di antara pemanggilan
dd if=/dev/random ...
sumber
dd if=/dev/random bs=1K count=2
berhenti ketika kolam entropi tampaknya terkuras. Dari dokumen, harus diblokir sampai ada lebih banyak entropi, sehinggadd
akan menulis file perlahan, bukan hanya membuang kolam saat ini dan keluar.read(fd, mybuf, 1024)
FD yang memblokir, ia akan kembali segera setelah perangkat yang mendasarinya mengembalikan beberapa data. Jika ada 1024 byte di sana untuk dibaca, ia mengembalikannya. Jika hanya ada 201 byte, ia akan mengembalikan 201. Jika ada 0 byte yang tersedia, ia akan memblokir hingga setidaknya satu byte tersedia, kemudian mengembalikannya.Mengapa
dd
data drop? ... Gilles telah mengajukan pertanyaan menarik tentangdd
:Kapan dd cocok untuk menyalin data? (atau, ketika dibaca () dan tulis () parsial)
Berikut adalah kutipan dari pertanyaan itu:
* ... tidak sulit menyalahkan dd; misalnya, coba kode ini: **
yes | dd of=out bs=1024k count=10
dan periksa ukuran file yang keluar (kemungkinannya di bawah 10MB).
Selain dari komentar saya (di akhir pertanyaan Anda), sesuatu seperti ini adalah iteresting untuk ditonton ... Ini menangkap byte Anda dalam file
$trnd
. Saya telah semi-sewenang-wenang memilih bs = 8Gerakkan mouse Anda dan perhatikan kecepatannya.
Dengan komputer saya menganggur (AFK dan tidak ada aktivitas Jaringan), dan setelah melelahkan kumpulan entropi, butuh 2 jam 12 menit untuk mengumpulkan hanya 1.192 byte, di mana saat itu saya membatalkannya.
Kemudian, dengan saya menggerakkan mouse terus-menerus, dibutuhkan waktu yang relatif lebih pendek 1 menit 15 detik untuk mengumpulkan jumlah byte yang sama.
Ini menunjukkan dengan cukup jelas bahwa mengumpulkan entropi bukan berdasarkan kecepatan CPU, melainkan berdasarkan kejadian acak , dan bahwa sistem Ubuntu saya menggunakan mouse sebagai salah satu faktor acak yang signifikan .
sumber
dd
adalah dirancang untuk memblokir - biasanya alat terbaik yang Anda inginkan untuk membaca dari input berukuran variabel jika Anda membutuhkannya dilakukan segera karenadd
tidak akan buffer saat membaca ke dalam beberapa masa depanwrite()
(kecuali jika Anda sangat eksplisit mengkonfigurasinya seperti itu dengan obs lebih besar dari IBS) , tetapi akan sebaliknyawrite()
semua yang dibacanya segera setelahread()
itu (dan secara opsional memprosesnya) .Berikut ini beberapa definisi penting :
ibs=
expr
expr
obs=
expr
expr
bs=
expr
expr
byte, menggantikanibs=
danobs=
. Jika tidak ada konversi selainsync
,,noerror
dannotrunc
ditentukan, setiap blok input harus disalin ke output sebagai satu blok tanpa mengagregasi blok pendek.Jadi Anda lihat, ketika
ibs
danobs
didefinisikan bersama sebagaibs
makaibs
diutamakan - tetapi sebaliknya, jika Anda tertentu, maka baikobs
ataucbs
tidak.Berikut adalah contoh yang
ibs
paling penting. Anda mungkin melakukan sesuatu seperti ini jika Anda ingin melacak seberapa cepat/dev/random
kolam diisi ...Asalkan
if=
target dapat dibaca sama sekali, itu akan selalu menghasilkan file output berukuran sama, karenadd
akansync
hronize blok read-in pada nulls. Dengan kata lain, jikadd
read()
s untuk input-blok$((size=10))
$((count=5))
kali danread()
file mengembalikan 2 byte, lalu 8 byte, lalu 12 byte, lalu 2 byte, maka 4 byte,dd
akan menulis ke sesuatu yang lebih besar dari file seperti... karena
dd
, secara default, tidak menunda. Jadi, jika Anda perlu melacak streaming dan membatasi penulisan beberapa proses lainnya,dd
adalah alat untuk Anda.Jika Anda hanya menulis sejumlah data ke file biasa, berlawanan dengan pernyataan lain yang dibuat di sini, Anda juga dapat menggunakan
dd
ini - dan cukup mudah - tetapi Anda akan membutuhkan lebih dari satu dan faktor pemblokiran yang andal .Misalnya, jika Anda melakukannya:
... yang pertama
dd
akan buffer sebanyak mungkinibs="$size"
blok input yang diperlukan untuk mengisi setidaknya satuobs="${size}x$block_factor"
blok output untuk setiapwrite()
ke pipa di antara itu dan yang keduadd
. Ini berarti bahwa yang keduadd
dapat membatasi output dengan andalcount="$lmt"
karena semuawrite()
s yang pertama dibuat akan cocok dengan blokir i / o - terlepas dari berapa banyakread()
yang pertamadd
harus dilakukan untuk membuatnya jadi.Dan itulah cara yang dapat Anda gunakan
dd
untuk secara andal membaca pipa atau jenis file khusus lainnya - hanya dengan sedikit matematika.sumber