【问题标题】:How can i create a truly random number in C (IDE: MPLAB)如何在 C 中创建真正的随机数(IDE:MPLAB)
【发布时间】:2018-05-11 19:13:28
【问题描述】:

我正在 PIC18F2550 上制作游戏,我需要创建一个介于 1 和 4 之间的随机数。 我已经发现 rand() 函数不适合真正的随机数。 我试过srand(time(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) "

我认为问题可能在于微处理器不“知道时间”,所以如果是这种情况,我该怎么做才能解决这个问题?

【问题讨论】:

  • 计算机(微控制器)程序是确定性的。需要一个外部熵源来生成“真正的”随机数。在您的情况下,这是时间,这并不是真正随机的。所以答案是——你不能,除非你有一些硬件来为你提供熵。但显然这根本不是你的问题。您可以使用连接了一些温度敏感电路的模拟输入来代替时间。

标签: c random build mplab microprocessors


【解决方案1】:

要初始化随机数发生器,您可以使用 PIC 的 ADC 读取浮动引脚上的电压,并使用 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。

【讨论】:

    【解决方案2】:

    由于您的 PIC 没有硬件 RNG,因此您必须接受软件 PRNG。是的,许多 C 库中的那个不是很好(尽管许多现代编译器正在变得更好)。对于小型嵌入式系统,我喜欢使用 Marsaglia 的 XOR 移位:

    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 以外)即可为上述内容播种。

    【讨论】:

    • 这不符合创建真正随机数的要求。事实上,如果算法是已知的,它是 100% 可预测的——将 1 添加到返回值并执行相同的计算集以获得下一个值。至少您应该使用 PRNG 将较大的状态折叠成返回值,以便状态与输出不是 1:1。
    【解决方案3】:

    “任何试图通过确定性方法生成随机数的人,当然都生活在罪恶之中。” - John von Neumann

    网上有真随机数的来源,比如LavaRnd

    只要没有连接麦克风,也可以从计算机的麦克风插座获得一些物理随机输入。这将提供可用作 TRNG 基础的热噪声。最好收集大量数据,至少 50 倍或更多位以确保安全,并使用质量好的密码散列函数提取熵。您需要进行实验,具体取决于您的设备提供多少熵。

    更复杂的是 Fortuna 或类似的完整实现,它从多个来源收集熵。

    最昂贵的方法是在卡上购买真正的随机源并安装它。

    【讨论】:

      猜你喜欢
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 2010-11-17
      • 2011-08-06
      相关资源
      最近更新 更多