Создание случайного двоичного файла
За что потребовалось 5 минут, чтобы создать 1 KiB файл на моей (младшей) ноутбуке с небольшой нагрузкой? И как я мог бы генерировать случайный двоичный файл быстрее?
$ 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
$
Обратите внимание, что dd if=/dev/random of=random-file bs=1024 count=1
не работает. Он генерирует случайный двоичный файл случайной длины, на большинстве прогонов до 50 В. Кто-нибудь объясняет это тоже?
Ответы
Ответ 1
Это означает, что в большинстве систем /dev/random
используются случайные данные из среды, такие как статические данные из периферийных устройств. Пул действительно случайных данных (энтропия), которые он использует, очень ограничен. Пока не появится больше данных, выходные блоки.
Повторите попытку с помощью /dev/urandom
(обратите внимание на u
), и вы увидите значительное ускорение.
Подробнее см. Wikipedia. /dev/random
не всегда выводит действительно случайные данные, но ясно, что в вашей системе это делает.
Пример с /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
Ответ 2
Попробуйте /dev/urandom
вместо этого:
$ time dd if=/dev/urandom of=random-file bs=1 count=1024
От: http://stupefydeveloper.blogspot.com/2007/12/random-vs-urandom.html
Основное различие между случайным и урбандом заключается в том, как они извлекают случайные данные из ядра. random всегда берет данные из энтропийного пула. Если пул пуст, случайный будет блокировать операцию до тех пор, пока пул не будет заполнен достаточно. urandom будет генерировать данные с использованием алгоритма SHA (или любого другого алгоритма, MD5 иногда) в случае, если пул энтропии ядра пуст. urandom никогда не блокирует операцию.
Ответ 3
Я написал script для тестирования различных скоростей хеширования. Для этого мне нужны файлы "случайных" данных, и я не хотел использовать один и тот же файл дважды, чтобы ни одна из функций не обладала преимуществом кеша ядра над другим. Я обнаружил, что оба /dev/random и/dev/urandom были очень медленными. Я решил использовать dd для копирования данных моего жесткого диска, начиная с случайных смещений. Я НИКОГДА не предлагал бы использовать это, если вы занимаетесь любыми вещами, связанными с безопасностью, но если все, что вам нужно, это шум, неважно, где вы его получите. На Mac используйте что-то вроде /dev/disk 0 в Linux, используя /dev/sda
Вот полный тест script:
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
Вот результаты "менее медленного" /dev/disk 0:
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
Вот результаты медленного /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
Вот самые медленные результаты /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
Вы заметите, что /dev/random и/dev/urandom не сильно отличаются по скорости. Тем не менее, /dev/disk 0 заняло 1/2 времени.
PS. Я уменьшаю количество тестов и удаляю все, кроме 2 команды, ради "краткости" (не то, что мне удалось быть кратким).
Ответ 4
Старый поток, но, как сказал Тоббе, мне нужно было что-то вроде этого лучше (быстрее).
Итак... shell-способ сделать то же самое, просто быстрее, чем случайный /urandom, полезный при создании действительно больших файлов, я допускаю, что не полностью случайный, но достаточно близко, вероятно, зависит от ваших потребностей.
dd if=/dev/mem of=test1G.bin bs=1M count=1024
touch test100G.bin
seq 1 100 | xargs -Inone cat test1G.bin >> test100G.bin
Это создаст файл 100Gb из содержимого вашего бара (первый 1GB, я предполагаю, что у вас столько бара:))
Обратите внимание, что также возможно небезопасно делиться этим файлом, так как он может содержать все виды конфиденциальных данных, таких как ваши пароли, поэтому используйте его только для своих собственных целей:) О, и вам нужно запустить его как root по той же самой причине.
Ответ 5
Старый поток, но мне просто нужно то же самое. Старый друг C пришел на помощь, так как я не хочу возиться со сценариями. Вот мое решение, которое хорошо и достаточно быстро для меня:
// 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);
}