Замените / dev / urandom на rand () - PullRequest
0 голосов
/ 09 мая 2020

В ubuntu программа использует

FILE *randomSource = fopen("/dev/urandom", "rb");
int byteCount = fread(buf, sizeof(unsigned char), num, randomSource);

И я хотел бы заменить это на rand () из stdlib, потому что мне нужно использовать его в среде, где нет / dev / urandom. Я пробовал вот так:

buf = malloc (num);
int i;

for (i = 0; i < num; i++)
{
  buf[i] = rand ();
}

Но, видимо, это не эквивалентно, потому что программа не работает. В результате должно получиться n случайных байтов, при этом buf указывает на первый.

Я тоже пробовал, но все равно не удалось.

randomBytes(unsigned char *buf, const int num)
{
    buf = malloc (num * sizeof *buf);
    int i;

    for (i = 0; i < num; i++)
    {
      buf[i] = rand ();
    }
    return 0;
}

Исходная функция, которую я пытаюсь заменить:

randomBytes(unsigned char *buf, const int num)
{
    FILE *randomSource = fopen("/dev/urandom", "rb");

    if (!randomSource)
    {
        return -1;
    }

    int byteCount = fread(buf, sizeof(unsigned char), num, randomSource);

    if (byteCount < num)
    {
        return -1;
    }

    fclose(randomSource);

    return 0;
}

Ответы [ 2 ]

2 голосов
/ 09 мая 2020

Вам не нужно malloc ничего в функции randomBytes(). Параметр buf уже указывает на буфер, достаточный для хранения num байтов. Все, что вам нужно сделать, это заполнить его.

randomBytes(unsigned char *buf, const int num)
{
    int i;

    for (i = 0; i < num; i++)
    {
      buf[i] = rand ();
    }
    return 0;
}

Когда вы сделали buf = malloc(), вы перезаписали свой параметр buf указателем на новый блок памяти и записали случайные байты в новый блок. Исходный блок, который вызывающий ожидал заполнить случайными байтами, не был затронут. Более того, выделенный вами новый блок никогда не освобождается, и после возврата randomBytes у вас больше нет указателей на него, поэтому он утекает. (Помните, что функции C передают аргументы по значению, поэтому само присвоение параметру buf не влияет ни на какие переменные в любых других функциях - хотя присвоение buf[i] - это совсем другая история.) не то, что вы хотите сделать.

Это можно было бы сделать немного более эффективным, поскольку rand() возвращает случайное значение от 0 до RAND_MAX, которое обычно составляет примерно 31 бит случайности, поэтому вы можете заполнить более одного байта на вызов rand(). Но этого определенно должно быть достаточно для начала.

Не забудьте вызвать srand() где-нибудь в вашей программе, если вы не хотите получать одну и ту же последовательность случайных байтов при каждом запуске.

Наконец, имейте в виду, что во многих системах rand() является генератором случайных чисел довольно низкого качества. В частности, его категорически нельзя использовать в каких-либо криптографических c целях или в азартных играх, где на кону стоят деньги.

1 голос
/ 09 мая 2020

Вы не объясняете, как программа дает сбой. Узнайте больше о rand и рассмотрите возможность заполнения своего PRNG . Возможно, вас заинтересует Твистер Мерсенна : на некоторых платформах это гораздо лучший ГПСЧ, чем rand. Без заполнения rand имеет воспроизводимое поведение .

Также mallo c может дать сбой, и вы не проверяете это. Если malloc не удается, buf равно NULL, и первый l oop вашего for вызывает undefined поведение : вы разыменовываете указатель NULL (возможно, это сегментация ошибка ).

Рекомендуемое чтение: Как отлаживать небольшие программы .

Рассмотрите возможность компиляции вашего кода на Ubuntu с gcc -Wall -Wextra -g. Вы можете получить полезные предупреждения.

Рассмотрите возможность использования valgrind в Ubuntu.

Я пробовал это

randomBytes(unsigned char *buf, const int num)
{
    buf = malloc (num * sizeof *buf);
    int i;

Вы перезапись переданного аргумента buf. Лучше еще даже не передавать его (и, возможно, вернуть такой буфер).

Пожалуйста, прочтите Современные C, а затем немного хороших C программирования Сайт , документация вашего отладчика (в Ubuntu, из GDB ), документация вашего компилятора (в Ubuntu, из G CC), затем стандарт C11 ( n1570 ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...