Как использовать/dev/random или urandom в C?

Я хочу использовать /dev/random или /dev/urandom в C. Как я могу сделать это? Я не знаю, как я могу обработать их в C, если кто-то знает, скажите мне как.Спасибо.

72
задан CodesInChaos 26 October 2013 в 22:02
поделиться

3 ответа

В общем, лучше избегать открытия файлов для получения случайных данных, поскольку в процедура.

В последних дистрибутивах 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);
}
98
ответ дан 24 November 2019 в 12:38
поделиться

Просто откройте файл для чтения, а затем прочтите данные. В C ++ 11 вы можете использовать std :: random_device , который обеспечивает межплатформенный доступ к таким устройствам.

16
ответ дан 24 November 2019 в 12:38
поделиться

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 заполняется за счет энтропии , поэтому он может блокироваться на длительное время в зависимости от обстоятельств.

8
ответ дан 24 November 2019 в 12:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: