Как я могу создать действительно случайное число в C (IDE: MPLAB) - PullRequest
0 голосов
/ 11 мая 2018

Я делаю игру на PIC18F2550, и мне нужно создать случайное число от 1 до 4. Я уже выяснил, что функция rand () отстой для действительно случайных чисел.Я пробовал srand (время (NULL)), это основной файл

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
void main(void) {
    srand(time(NULL));
    init(); 
    while(timed_to_1ms()) {
        fsm_game();
    }
}

, это файл fsm_game.c

void randomSpawn(int time2) {
    if(counter%time2==0) { 
        int x = rand()%4 +1; // Makes number between 1 and 4
    }
}

Когда я пытаюсь собрать это, яполучить сообщение об ошибке:

": 0: ошибка: (499) неопределенный символ: _time (dist / default / production \ Dontcrash.production.obj)"

Я думаю, что проблема может бытьв том факте, что микропроцессор не «знает время», поэтому, если это так, что я могу сделать, чтобы решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Для инициализации генератора случайных чисел вы можете прочитать напряжение, присутствующее на плавающем выводе, с помощью АЦП PIC, и установить начальное значение с помощью srand () .

. Кроме того, вы можете сохранитьначальное значение EEPROM при каждом запуске программы и чтение предыдущего начального значения из EEPROM, объедините его со значением ADC, чтобы сделать вещи менее предсказуемыми.- Я думаю, что это было бы достаточно для игры, в противном случае это было бы слишком грубо, я думаю.

unsigned int seed = read_seed_from_adc();
seed ^= read_seed_from_eeprom(); /* use something else than XOR here */
srand(seed);
write_seed_to_eeprom(seed);

Я думаю, что проблема может быть в том, что микропроцессор не «знает»время », так что, если это так, что я могу сделать, чтобы решить эту проблему?

Время обычно измеряется с помощью RTC на микроконтроллере, поэтому зависит от вашего оборудования, если RTC может бытьиспользуется (RTC обычно требуется кварцевый резонатор и резервная батарея, чтобы постоянно работать, некоторые микро используют внешний RTC).Поскольку чаще всего на микроконтроллерах используется только небольшая библиотека C, time () обычно будет недоступна, и вам придется считывать регистры RTC самостоятельно.- Его также можно использовать для инициализации PRNG.

0 голосов
/ 13 мая 2018

«Любой, кто пытается генерировать случайные числа детерминистскими средствами, конечно, живет в состоянии греха». - Джон фон Нейман

В Интернете есть источники истинных случайных чисел, такие как LavaRnd .

Также возможно получить некоторый физический случайный вход от гнезда микрофона вашего компьютера, если микрофон не подключен. Это создаст тепловой шум, который можно использовать в качестве основы для ТРНГ. Лучше всего собирать большое количество данных, по крайней мере, в пятьдесят раз больше битов или больше для безопасности, и извлекать энтропию с помощью криптографической хэш-функции хорошего качества. Вам нужно будет экспериментировать, в зависимости от того, сколько энтропии доставляет ваше оборудование.

Более сложной была бы полная реализация Фортуна или аналогичная, которая собирает энтропию из ряда источников.

Самым дорогим было бы купить настоящий случайный источник на карте и установить его.

0 голосов
/ 11 мая 2018

Поскольку в вашем ПОС отсутствует аппаратная ГСЧ, вам придется согласиться на программную ГСЧ. Да, во многих C библиотеках не очень хорошо (хотя многие современные компиляторы становятся лучше). Для небольших встраиваемых систем мне нравится использовать XOR-смещение Marsaglia:

static uint32_t rng_state;
uint32_t rng_next() {
    rng_state ^= (rng_state << 13);
    rng_state ^= (rng_state >> 17);
    rng_state ^= (rng_state << 5);
    return rng_state - 1;
}

Вы заполняете вышесказанное, просто устанавливая rng_state в начальное значение (отличное от 0).

...