私はubuntuシステムで次のコマンドを実行しています:
dd if=/dev/random of=rand bs=1K count=2
ただし、実行するたびに、サイズの異なるファイルが作成されます。どうしてこれなの?ランダムデータで満たされた特定のサイズのファイルを生成するにはどうすればよいですか?
iflag=fullblock
私はubuntuシステムで次のコマンドを実行しています:
dd if=/dev/random of=rand bs=1K count=2
ただし、実行するたびに、サイズの異なるファイルが作成されます。どうしてこれなの?ランダムデータで満たされた特定のサイズのファイルを生成するにはどうすればよいですか?
iflag=fullblock
回答:
dd
の特異な動作とLinuxの特異な動作の組み合わせを観察しています/dev/random
。ちなみに、両方が仕事に適したツールになることはめったにありません。
Linux /dev/random
はデータを控えめに返します。これは、疑似乱数ジェネレーターのエントロピーが非常に高速で消滅するという仮定に基づいています。新しいエントロピーの収集は遅いため、/dev/random
通常は一度に数バイトしか放棄しません。
dd
当初はテープデバイス上で動作することを目的とした、不気味な古いプログラムです。1kBの1ブロックを読み取るように指示すると、1ブロックを読み取ろうとします。読み取りから1024バイト未満が返された場合は、それで十分です。したがってdd if=/dev/random bs=1K count=2
、2つのread(2)
呼び出しを行います。から読み取るため/dev/random
、2つのread
呼び出しは通常、使用可能なエントロピーに応じてさまざまな数で、数バイトのみを返します。こちらもご覧くださいデータをコピーするのに適したDDですいつですか?(または、read()およびwrite()が部分的である場合)
OSインストーラーまたはクローンを設計する場合を除き、/dev/random
Linuxでは常に使用しないでください/dev/urandom
。urandom
manページは、やや誤解を招くです。/dev/urandom
実際には、寿命の長いキーを生成する場合でも、暗号化に適しています。唯一の制限/dev/urandom
は、十分なエントロピーを提供する必要があることです。Linuxディストリビューションは通常、再起動間のエントロピーを保存するため、十分なエントロピーがない可能性があるのは、新規インストール時のみです。エントロピーは、実用的な意味では衰えません。詳細については、「/ dev / urandomからのランドはログインキーに対して安全ですか?」を参照してください。と/ dev / randomエントロピープールのフィード?。
のほとんどの使用法はdd
、head
またはなどのツールでより適切に表現されますtail
。2kBのランダムバイトが必要な場合は、実行します
head -c 2k </dev/urandom >rand
古いLinuxカーネルを使用すると、
dd if=/dev/urandom of=rand bs=1k count=2
/dev/urandom
幸いにも要求されただけのバイトを返したからです。しかし、これはカーネル3.16以降では当てはまらず、現在は32MBに制限されています。
一般に、dd
固定数のバイトを抽出するために使用する必要があり、その入力が通常のファイルまたはブロックデバイスから来ていない場合、バイトごとに読み取る必要がありますdd bs=1 count=2048
。
/dev/urandom
ごとに32mが返されますread()
。
dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
man 4 random
RHEL 5のボックスに:
読み取られると、/ dev / randomデバイスは、エントロピープール内のノイズの推定ビット数内のランダムバイトのみを返します。
そのマシンで213バイトのサイズのファイルを取得します。男4ランダムに戻る:
/ dev / urandomデバイスは、読み取られると、要求されたバイト数を返します。
のすべての呼び出しから2048バイトを取得します dd if=/dev/urandom of=rand bs=1K count=2
私は、違いは、マシンが呼び出しの間にどれだけのエントロピーを生成するためであると結論付けます dd if=/dev/random ...
dd if=/dev/random bs=1K count=2
、エントロピープールが明らかに流出したときに停止する理由について私は困惑しています。ドキュメントから、エントロピーが増加するまでブロックする必要があるためdd
、現在のプールをダンプして終了するのではなく、ファイルをゆっくりと書き出します。
read(fd, mybuf, 1024)
阻止FDに、それはすぐに基本となるデバイスが返すようとして返すいくつかのデータを。読み込む1024バイトがある場合、それを返します。201バイトしかない場合、201を返します。0バイトが使用可能な場合、少なくとも1バイトが使用可能になるまでブロックし、それを返します。
dd
データをドロップするのはなぜですか?... ジルはについては、この魅力的疑問を提起しましたdd
:
データをコピーするための適切なDDですいつですか?(または、read()およびwrite()が部分的である場合)
その質問からの抜粋を次に示します。
* ... ddを誤解させるのは難しくありません。たとえば、次のコードを試してください:**
yes | dd of=out bs=1024k count=10
、outファイルのサイズを確認します(10MBを大きく下回る可能性が高い)。
(質問の最後の)私のコメントは別として、次のようなものは見ていて面白くて...ファイル内のバイトをキャッチします。 $trnd
。私は半任意にbs = 8を選択しました
マウスを動かして、速度が上がるのを見てください。
コンピューターがアイドル状態(AFKおよびネットワークアクティビティなし)で、エントロピープールを使い果たした後、1192バイトのみを収集するのに2 時間 12分かかり、その時点でキャンセルしました。
次に、マウスを連続的に動かして、同じバイト数を収集するのに比較的短い1 分 15秒かかりました。
これは、エントロピーの収集がCPU速度ベースではなく、ランダムイベントベースであり、Ubuntuシステムが重要なランダム要素の1つとしてマウスを使用していることを明確に示しています。
get=2048
trnd=/tmp/$USER.rnd; >"$trnd"
while (( $(wc -c <"$trnd") < $get )) ;do
dd if=/dev/random bs=8 count=1 2>/dev/null >>"$trnd"
echo -n "itt: $((i+=1)) ct: "; wc -c <"$trnd"
done
truncate -s $get "$trnd"
echo -e "\nfinal count: "; wc -c <"$trnd"
dd
されて設計された、ブロッキングのために-それは通常、あなたの処分で最高のツールである可変サイズの入力から読み込みを行うためのあなたがそれを行う必要がある場合は、直ちにので、dd
現在のバッファリングはありませんいくつかの未来に読み込むwrite()
(あなたは非常に明確にIBSよりも大きなOBSでそのように設定しない限り)、しかし、代わりにwrite()
、それが読み込まれるとすぐread()
に(そしてオプションでそれを処理する)すべてを読みます。
ibs=
expr
expr
obs=
expr
expr
bs=
expr
expr
、バイト取って代わるibs=
とobs=
。より変換なし他の場合sync
、noerror
およびnotrunc
指定され、各入力ブロックはショートブロックを集約することなく、単一のブロックとして出力にコピーされなければなりません。あなたが見るので、ときibs
とobs
として一緒に定義されbs
、その後ibs
、あなたはどちらか、その後、特定されている場合は、そうでないが、 -優先されますobs
か、cbs
しません。
ibs
最も重要な例を次に示します。/dev/random
プールがいっぱいになるのを追跡したい場合は、このようなことをするかもしれません...
dd "ibs=$size" conv=sync "count=$lmt" \
if=/dev/random of="$somefile"
限りif=
の目標は、すべての読み取り可能である、それはなります常にので、同じサイズの出力ファイルになりdd
ますsync
ブロックは、読み取りにヌルにhronize。つまり、dd
read()
入力ブロックのsがsで$((size=10))
$((count=5))
、read()
ファイルが2バイト、8バイト、12バイト、2バイト、4バイトのいずれdd
かを返す場合、次のような出力ファイルに書き込みます。
2 read bytes 8NULs \
8 read bytes 2NULs \
10 read bytes 0NULs \
4 read bytes 6NULs \
4 read bytes 6NULs
... dd
デフォルトでは、遅延しません。したがって、インストリームを追跡し、他のプロセスの書き込みを制限する必要がある場合、dd
は、このツールがです。
一定量のデータを通常のファイルに書き込む場合、ここで行われた他のステートメントとは異なり、これにも使用できますdd
-かなり簡単ですが-複数の信頼性の高いブロックファクターが必要になりますです。
たとえば、次の場合:
{ dd ibs="$size" obs="${size}x$block_factor" |
dd bs="${size}x$blockfactor" "count=$lmt"
} <infile >outfile
...最初のブロックは、そのブロックと2番目のブロックの間のパイプのすべてに対して少なくとも1つの出力ブロックを満たすために必要なdd
数のibs="$size"
入力ブロックをバッファリングします。これは、最初に行う必要があるsの数に関係なく、最初に作成するすべてのsがそのI / Oブロックサイズと一致するため、2番目の出力が確実に出力を制限できることを意味します。obs="${size}x$block_factor"
write()
dd
dd
count="$lmt"
write()
read()
dd
そして、それdd
はパイプや他の種類の特殊ファイルをほんの少しの数学で確実に読み取るために使用できる方法です。
/dev/random
必要な桁数を生成するのに十分なエントロピーがない場合、ブロックします。高品質の疑似ランダム「ランダム性」の量を収集するのに時間がかかるだけです...ランダム性/dev/urandom
の低い「ランダム」値を使用するか、エントロピープールを確認します(ループで、必要に応じて待機します)...