Я запускаю следующую команду в системе Ubuntu:
dd if=/dev/random of=rand bs=1K count=2
Однако каждый раз, когда я запускаю его, я получаю файл другого размера. Почему это? Как я могу создать файл заданного размера, заполненный случайными данными?
/dev/random
будет блокироваться, если энтропии недостаточно для создания необходимого количества цифр. это просто нужно время , чтобы собрать такое количество высококачественной псевдо случайной «случайность» ... Либо использовать/dev/urandom
для менее случайного «случайного» значения, или проверить пул энтропии (в цикле, и ждать , как потребность быть) ...iflag=fullblock
Ответы:
Вы наблюдаете комбинацию специфического поведения
dd
со специфическим поведением Linux/dev/random
. Оба, кстати, редко являются подходящим инструментом для работы.Linux
/dev/random
возвращает данные экономно. Он основан на предположении, что энтропия в генераторе псевдослучайных чисел гасится с очень высокой скоростью. Так как сбор новой энтропии происходит медленно,/dev/random
обычно сбрасывает только несколько байтов за раз.dd
это старая, капризная программа, изначально предназначенная для работы на ленточных устройствах. Когда вы говорите ему прочитать один блок размером 1 КБ, он пытается прочитать один блок. Если чтение возвращает менее 1024 байтов, это все, что вы получите. Так чтоdd if=/dev/random bs=1K count=2
делает дваread(2)
звонка. Поскольку он считывает данные/dev/random
, дваread
вызова, как правило, возвращают только несколько байтов с различным числом в зависимости от доступной энтропии. Смотрите также, Когда dd подходит для копирования данных? (или, когда read () и write () частично)Если вы не разрабатываете установщик ОС или клонер, вы никогда не должны использовать его
/dev/random
под Linux, всегда/dev/urandom
. Страницаurandom
man несколько вводит в заблуждение;/dev/urandom
на самом деле подходит для криптографии, даже для генерации долгоживущих ключей. Единственное ограничение/dev/urandom
состоит в том, что он должен быть снабжен достаточной энтропией; Обычно дистрибутивы Linux сохраняют энтропию между перезагрузками, поэтому единственный раз, когда вам может не хватить энтропии, это новая установка. Энтропия не стирается в практическом плане. Дополнительную информацию смотрите в разделе Безопасен ли rand из / dev / urandom для ключа входа? и кормление / dev / случайный пул энтропии? ,Большинство применений
dd
лучше выражены с помощью таких инструментов, какhead
илиtail
. Если вы хотите 2 КБ случайных байтов, запуститеСо старыми ядрами Linux вы могли бы
потому что
/dev/urandom
счастливо вернул столько байтов, сколько просил. Но это больше не так с ядра 3.16, теперь оно ограничено 32 МБ .В общем случае , когда вам нужно использовать ,
dd
чтобы извлечь фиксированное количество байт и его вход не из обычного файла или блочного устройства, вам необходимо прочитать побайтно:dd bs=1 count=2048
.источник
/dev/urandom
возвращается 32млнread()
.dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
С
man 4 random
коробки RHEL 5:Я получаю файлы размером 213 байт на этой машине. Вернуться к человеку 4 случайным образом:
Я получаю 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 байт, он заблокируется, пока не станет доступен хотя бы один байт, а затем вернет его / их.Почему
dd
сбрасывают данные? ... Жиль поставил этот занимательный вопрос оdd
:Когда д.д. подходит для копирования данных? (или, когда read () и write () частично)
Вот выдержка из этого вопроса:
* ... не сложно поставить дд вину; например, попробуйте этот код: **
yes | dd of=out bs=1024k count=10
и проверьте размер выходного файла (он, вероятно, будет меньше 10 МБ).
Помимо моего комментария (в конце вашего вопроса), что-то вроде этого интересно посмотреть ... Он ловит ваши байты в файле
$trnd
. Я полу произвольно выбрал bs = 8Двигай мышью и наблюдай, как она ускоряется.
Когда мой компьютер простаивает (AFK и нет сетевой активности) и после исчерпания энтропийного пула потребовалось 2 часа 12 минут, чтобы собрать только 1192 байта, после чего я отменил его.
Затем, когда я непрерывно двигал мышью, мне потребовалась относительно короткая 1 минута 15 секунд, чтобы собрать то же количество байтов.
Это довольно ясно показывает, что сбор энтропии не основан на скорости процессора, а скорее основан на случайных событиях , и что моя система Ubuntu использует мышь в качестве одного из значительных случайных факторов.
источник
dd
будет предназначен для блокирования - это, как правило , самый лучший инструмент в вашем распоряжении для чтения входных переменных размеров , если вам это нужно сделать немедленно , потому чтоdd
не будет текущий буфер читает в какой - то будущееwrite()
(если вы очень явно не настроить его таким образом с более крупными набл чем СРК) , но будет вместо этого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
бассейн заполнится ...Пока
if=
цель вообще читаема, это всегда будет приводить к выходному файлу одинакового размера, потому чтоdd
будетsync
хронизировать чтение блоков с нулями. Другими словами, еслиdd
read()
s для блока ввода$((size=10))
$((count=5))
времен иread()
файл возвращает 2 байта, то 8 байтов, затем 12 байтов, затем 2 байта, а затем 4 байта,dd
запишет в свой выходной файл что-то вроде... потому что
dd
, по умолчанию, не задерживается. Так что если вам нужно отслеживать в потоке и разделять записи какого-либо другого процесса,dd
это инструмент для вас.Если вы просто записываете некоторый объем данных в обычный файл, тогда, в отличие от других заявлений, сделанных здесь, вы также можете использовать
dd
это - и довольно легко - но вам потребуется более одного и надежный фактор блокировки .Например, если вы сделали:
... первый
dd
буферизует столькоibs="$size"
входных блоков, сколько необходимо, чтобы заполнить хотя бы одинobs="${size}x$block_factor"
выходной блок для каждогоwrite()
канала в канале между ним и вторымdd
. Это означает, что второйdd
может надежно ограничить вывод,count="$lmt"
потому что всеwrite()
s, которые делает первое, будут соответствовать его размеру блока ввода / вывода - независимо от того, сколькоread()
sdd
должно сделать первое , чтобы сделать это.И что «S , как вы можете использовать ,
dd
чтобы надежно прочитанные трубы или другие тип специальных файлов - с помощью всего лишь немного математики.источник