AVR Atmega128范围内的随机数生成器

时间:2018-06-21 17:55:43

标签: c random avr atmega

我正在和朋友一起为ATmega128进行研究项目,我们对随机数生成器(从0到5)存在问题,因为该函数始终显示相同的结果。我们无法添加time.h,因为AVR Studio不接受。

以下代码:

uint8_t randomNumber(uint8_t r){
r = rand()%5;
return r;
}

其他尝试

uint8_t randomNumber(uint8_t min, uint8_t max){
uint8_t = result;
result = min + rand() % (max+1 - min);
return result;
}

有什么想法吗? 谢谢, 塞巴斯蒂安

1 个答案:

答案 0 :(得分:2)

哇,这个问题把我送进了兔子洞。

  1. 伪随机数相对容易生成。
  2. 真正的随机数很难生成。
  3. 您的随机数的质量(是否出现偏差)完全取决于您的种子值。
  4. 随机数生成器的种子值必须是(等待)随机的,否则人们可以猜测您正在使用哪个数字,从而破坏了生成器的随机性。

从哪里获得随机种子值?

互联网提出的选项:

  1. 来自环境的自然噪声(读取adc或... https://www.fourmilab.ch/hotbits/(我知道这对于arduino项目不切实际,但仍然很有趣))。
  2. 时间用户输入(默认情况下,人类是不精确的)。
  3. 计时晶体之间的差异。 [https://en.wikipedia.org/wiki/Clock_drift]

轻度免责声明: 1/3已被证明在商业环境中是不安全的,并且很容易看到如何使用计算机而不是人类来玩#2。

因此,最快的方法可能是使用浮动ADC。在您认为这是一个好主意之前:https://skemman.is/bitstream/1946/10689/1/ardrand.pdf

请记住:更大的种子库会增加随机性(aka使用32位随机种子值比使用布尔型随机种子值还好)。

128个上的ADC具有1024个值,实际上,浮点值的趋势将远远小于该值(我读过,您应该将其视为32)。

为提高获得随机数的机会,请多次读取ADC读数中的最低位(也就是读取ADC以获得16位“随机”数)。

假设您已设置ADC等。

未验证的伪代码

/* srand example */
#include <stdio.h>      /* printf, NULL */
#include <stdlib.h>     /* srand, rand */
#include <avr/io.h>

//pseudo code.  you must implement init_adc() and read_adc()
int main ()
{
  //Init and seed.
  uint16_t u_rand_val = 0;
  uint16_t u_seed_rand_val = 0;

  init_adc();
  //Note we're assuming the channel that you are reading from is FLOATING or hooked up to something very noisy.  
  //Gather bits from the adc, pushing them into your pseudorandom seed.
  for(uint8_t i=0; i<16; i++){
      u_seed_rand_val = u_seed_rand_val<<1 | (read_adc()&0b1);
      }
  srand (u_seed_rand_val);

  while(1){
       //Do whatever you were going to do.
       //Note that calls to rand() use the seed set up by srand above.
       u_rand_val = rand()%5;
       print("Cur val:%u", u_rand_val);
       }
  return 0;
}