Я хочу использовать /dev/random
или /dev/urandom
в C. Как я могу сделать это? Я не знаю, как я могу обработать их в C, если кто-то знает, скажите мне как.Спасибо.
В общем, лучше избегать открытия файлов для получения случайных данных, поскольку в процедура.
В последних дистрибутивах Linux системный вызов getrandom
может использоваться для получения криптозащищенных случайных чисел, и он не может дать сбой , если GRND_RANDOM
равно не , заданный как флаг, а объем считывания составляет не более 256 байт.
По состоянию на октябрь 2017 года OpenBSD, Darwin и Linux (с -lbsd
) теперь имеют реализацию arc4random
, которая является криптобезопасной и не может дать сбой.Это делает его очень привлекательным вариантом:
char myRandomData[50];
arc4random_buf(myRandomData, sizeof myRandomData); // done!
В противном случае вы можете использовать случайные устройства, как если бы они были файлами. Вы читаете из них и получаете случайные данные. Я использую open
/ read
здесь, но fopen
/ fread
будет работать так же хорошо.
int randomData = open("/dev/urandom", O_RDONLY);
if (randomData < 0)
{
// something went wrong
}
else
{
char myRandomData[50];
ssize_t result = read(randomData, myRandomData, sizeof myRandomData);
if (result < 0)
{
// something went wrong
}
}
Вы можете прочитать намного больше случайных байтов перед закрытием файлового дескриптора. / dev / urandom никогда не блокируется и всегда заполняет столько байтов, сколько вы запросили, если системный вызов не прерывается сигналом. Он считается криптографически безопасным и должен быть вашим случайным устройством.
/ dev / random более привередлив. На большинстве платформ он может возвращать меньше байтов, чем вы просили, и может блокироваться, если доступно недостаточно байтов. Это усложняет историю обработки ошибок:
int randomData = open("/dev/random", O_RDONLY);
if (randomData < 0)
{
// something went wrong
}
else
{
char myRandomData[50];
size_t randomDataLen = 0;
while (randomDataLen < sizeof myRandomData)
{
ssize_t result = read(randomData, myRandomData + randomDataLen, (sizeof myRandomData) - randomDataLen);
if (result < 0)
{
// something went wrong
}
randomDataLen += result;
}
close(randomData);
}
Просто откройте файл для чтения, а затем прочтите данные. В C ++ 11 вы можете использовать std :: random_device
, который обеспечивает межплатформенный доступ к таким устройствам.
Zneak верен на 100%. Также очень распространено чтение буфера случайных чисел, который немного больше, чем то, что вам понадобится при запуске. Затем вы можете заполнить массив в памяти или записать их в свой собственный файл для последующего повторного использования.
Типичная реализация вышеизложенного:
typedef struct prandom {
struct prandom *prev;
int64_t number;
struct prandom *next;
} prandom_t;
Это становится более или менее похоже на ленту, которая только что продвигается, которая может быть волшебным образом пополнена другим потоком по мере необходимости. Есть лот из сервисов , которые предоставляют большие дампы файлов только случайных чисел, которые генерируются гораздо более мощными генераторами, такими как:
Не используйте «заранее упакованную» энтропию для криптографической семена , на всякий случай. Эти наборы подходят для моделирования, совсем не подходят, для генерации ключей и тому подобного.
Не заботясь о качестве, если вам нужно много чисел для чего-то вроде симуляции Монте-Карло, гораздо лучше иметь их доступными таким образом, чтобы не вызывать блокировку read ().
Однако помните, что случайность числа так же детерминирована, как и сложность его генерации. / dev / random
и / dev / urandom
удобны, но не так эффективны, как использование HRNG (или загрузка большого дампа из HRNG). Также стоит отметить, что / dev / random
заполняется за счет энтропии , поэтому он может блокироваться на длительное время в зависимости от обстоятельств.