Создание большого файла случайных байтов быстро
Я хочу создать большой файл ~10G, заполненный нулями и случайными значениями. Я пытался с помощью:
dd if=/dev/urandom of=10Gfile bs=5G count=10
он создает файл размером около 2 Гб и выходит со статусом выхода 0. Я не понимаю, почему?
Я также попытался создать файл, используя:
head -c 10G </dev/urandom >myfile
но его создание занимает около 28-30 минут. Но я хочу, чтобы это создавалось быстрее. У кого-нибудь есть решение?
Также я хочу создать несколько файлов с одинаковым (псевдо) случайным рисунком для сравнения. Кто-нибудь знает способ сделать это? Спасибо
7 ответов
Я видел довольно аккуратный трюк в командной строке: использовать /dev/urandom
в качестве источника случайности (это хороший источник), а затем использовать его в качестве пароля для потокового шифра AES.
Я не могу сказать вам с уверенностью на 100%, но я верю, что если вы измените параметры (т.е. используйте более 128 байтов от /dev/urandom
), он, по крайней мере, достаточно близок к криптографически безопасному PRNG для всех практических целей:
Эта команда генерирует псевдослучайный поток данных, используя aes-256-ctr с начальным значением, заданным /dev/urandom. Перенаправить на блочное устройство для безопасного шифрования данных.
openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt < /dev/zero > randomfile.bin
Как это работает?
openssl enc -aes-256-ctr
буду использовать openssl
шифровать нули с помощью AES-256 в режиме CTR.
Что это зашифрует?
/dev/zero
Какой пароль он будет использовать для шифрования?
dd if=/dev/urandom bs=128 count=1 | base64
Это один блок из 128 байтов
/dev/urandom
закодирован в base64 (перенаправление на/dev/null
это игнорировать ошибки).Я на самом деле не уверен, почему
-nosalt
используется, поскольку на странице руководства OpenSSL указано следующее:-salt use a salt in the key derivation routines. This is the default. -nosalt don't use a salt in the key derivation routines. This option SHOULD NOT be used except for test purposes or compatibility with ancient versions of OpenSSL and SSLeay.
Возможно, дело в том, чтобы сделать это как можно быстрее, и использование солей было бы неоправданным, но я не уверен, оставит ли это какой-либо паттерн в зашифрованном тексте. Ребята из Cryptography Stack Exchange могут дать нам более подробное объяснение этого.
Вход
/dev/zero
, Это потому, что на самом деле не имеет значения, что шифруется - на выходе будет что-то, похожее на случайные данные. Нули можно быстро получить, и вы можете получить (и зашифровать) столько, сколько хотите, не исчерпывая их.Выход
randomfile.bin
, Это также может быть/dev/sdz
и вы бы рандомизировали полное блочное устройство.
Но я хочу создать файл с фиксированным размером! Как я могу это сделать?
Просто!
dd if=<(openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt < /dev/zero) of=filename bs=1M count=100 iflag=fullblock
Просто dd
эта команда с фиксированной blocksize
(что составляет 1 МБ здесь) и count
, Размер файла будет blocksize * count
= 1M * 100 = 100M.
Я получаю хорошие скорости, используя shred
полезность.
- 2G с
dd in=/dev/urandom
- 250сек - 2G с
openssl rand
- 81сек - 2G с
shred
- 39сек
Так что я ожидаю около 3-4 минут для 10G с shred
,
Создайте пустой файл и уничтожьте его, передав желаемый размер файла.
touch file
shred -n 1 -s 10G file
Я не уверен, насколько криптографически безопасны сгенерированные данные, но это выглядит случайным образом. Вот немного информации об этом.
Есть программа генератора случайных чисел sharand
, он записывает случайные байты в файл. (Первоначально программа называлась sharnd, на одну букву меньше (см. http://mattmahoney.net/dc/).
Это занимает примерно треть времени по сравнению с чтением /dev/urandom
Это безопасный RNG - есть более быстрый, но не безопасный RNG, но обычно это не то, что нужно.
Чтобы быть действительно быстрым, ищите набор алгоритмов RNG для Perl: libstring-random-perl
,
Давайте попробуем (apt-get install sharand
):
$ time sharand a 1000000000
sharand a 1000000000 21.72s user 0.34s system 99% cpu 22.087 total
$ time head -c 1000000000 /dev/urandom > urand.out
head -c 1000000000 /dev/urandom > urand.out 0.13s user 61.22s system 99% cpu 1:01.41 total
И файлы результатов - (они выглядят более случайными изнутри):
$ ls -l
-rw-rw-r-- 1 siegel siegel 1000000000 Aug 5 03:02 sharand.out
-rw-rw-r-- 1 siegel siegel 1000000000 Aug 5 03:11 urand.out
Сравнивая "общие" значения времени, sharand
заняло только треть времени, необходимого для метода urandom, чтобы создать чуть меньше гигабайта случайных байтов:
sharand
: Всего 22 urandom
: Всего 61с
Вам нужен специальный файл в Linux, /dev/random служит генератором случайных чисел в системе Linux. / dev / random будет в конечном итоге блокироваться, если ваша система не имеет большой активности, / dev / urandom в неблокировании. Мы не хотим блокировать при создании наших файлов, поэтому мы используем / dev / urandom.
попробуйте эту команду:
dd if=/dev/urandom bs=1024 count=1000000 of=file_1GB conv=notrunc
Это создаст файл с числом случайных байтов bs *, в нашем случае 1024*1000000 = 1 ГБ. Файл не будет содержать ничего читаемого, но в нем будут некоторые новые строки.
xKon@xK0n-ubuntu-vm:~/tmp$ dd if=/dev/urandom of=file.txt bs=1048576 count=100 conv=notrunc
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 13.4593 s, 7.8 MB/s
xKon@xK0n-ubuntu-vm:~/tmp$ wc -l file.txt
410102 file.txt
Вы можете использовать опцию seek с dd, чтобы ускорить процесс:
$ dd if=/dev/zero of=1g.img bs=1 count=0 seek=1G
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 8.12307 s, 132 MB/s
$ ls -lh t
-rw-rw-r-- 1 xK0n xK0n 1.1G 2014-08-05 11:43 t
Недостатками здесь являются тот факт, что файл не содержит ничего читаемого и тот факт, что он немного медленнее, чем метод /dev/zero (около 10 секунд для 100 Мб).
Вам также может понравиться команда fallocate, которая предварительно выделяет пространство для файла.
fallocate -l 1G test.img
выход
-rw-р -r--. 1 xK0n xK0n 1.0G Авг 05 11:43 test.img
Поскольку такого инструмента не было, я создал многопоточный быстрый генератор случайных данных.
pip install fastrandom
fastrandom > /dev/yourdisk
Шифрование OpenSSL, как упоминалось в других ответах, является одним из самых быстрых способов создания случайных данных, но для этого будет использоваться только одно ядро ЦП. Я могу получить около 3 ГБ/с с помощью aes-256-ctr или chacha20, тогда как мой собственный инструмент достигает скорости около 4,5 ГБ/с на реальных устройствах (11 ГБ/с для /dev/null).
openssl enc -chacha20 -nosalt -kfile /dev/urandom -in /dev/zero \
| dd of=/dev/yourdisk bs=1M status=progress
Интересно, что шифрование является самым быстрым способом создания случайных чисел. Даже лучшие современные генераторы случайных чисел, такие как PCG64, не могут работать так быстро (у меня получается около 1 ГБ/с на ядро). Оба метода создают очень хорошие псевдослучайные числа, поэтому имеет смысл просто использовать шифрование для всех нужд PRNG.
Два примера с openssl:
while true; do openssl rand 2147483647; done
Вы также можете зашифровать сгенерированный поток байтов, например, с помощью шифра aes-256-ctr:
while true; do openssl rand 2147483647; done | openssl enc -e -aes-256-ctr -k $(pwgen -ync 40 1) -pbkdf2 | pv > /dev/null
БЫСТРЫЙ И ГРЯЗНЫЙ И САМЫЙ БЫСТРЫЙ способ (без установки дополнительных утилит) просто:
cat /dev/urandom > random.bin
В другом окне терминала просто повторно используйте
ls -lh
контролировать размер . Когдаrandom.bin
достигнет нужного размера, вернитесь в исходное окно и нажмитеCtrl+c
Я попробовал несколько из вышеперечисленных методов одновременно в нескольких окнах терминала на одной и той же машине (хотел заполнить диск емкостью 2 ТБ случайными данными), и это был последний, который я выбрал, и он очень быстро догнал и обогнал все остальные методы. - примерно в 2-3 раза быстрее!
ЕЩЕ БЫСТРЕЕ — если вас устраивают нули, а не случайные данные, используйте
cat /dev/zero > fileofzeros.bin