Random 如何在微控制器中高效地生成随机数?

Random 如何在微控制器中高效地生成随机数?,random,microcontroller,Random,Microcontroller,如何在微控制器中高效地生成随机数?是否有任何通用指南或特定的快速方法?您可以通过模拟线性反馈移位寄存器来操纵位来生成伪随机数 然后问题就变成了“你想模拟多少比特?” 有一些信息。如果您可以访问ADC,则可以从中读取最低有效位,并将其用作伪随机数生成器的种子,就像其他人发布的一样。显然,您需要从ADC读取多个位,因此需要多次读取,这可能需要一段时间。但您只需要在启动时执行一次,然后使用更快的PRNG生成新的随机数 许多嵌入式设备都内置了inn ADC,例如ATMega系列表单Atmel。一个通常生

如何在微控制器中高效地生成随机数?是否有任何通用指南或特定的快速方法?

您可以通过模拟线性反馈移位寄存器来操纵位来生成伪随机数

然后问题就变成了“你想模拟多少比特?”


有一些信息。

如果您可以访问ADC,则可以从中读取最低有效位,并将其用作伪随机数生成器的种子,就像其他人发布的一样。显然,您需要从ADC读取多个位,因此需要多次读取,这可能需要一段时间。但您只需要在启动时执行一次,然后使用更快的PRNG生成新的随机数


许多嵌入式设备都内置了inn ADC,例如ATMega系列表单Atmel。

一个通常生成伪随机数,而不是实际随机数,尽管两者都可以以不同的速率生成

根据序列是否用于加密目的,通常有两种类型。主要区别在于序列中一个数字的知识是否允许预测下一个数字。通用RNG不担心算法知识是否允许观察者复制序列,而且它们运行速度相当快

一个典型的通用RNG算法是。有许多不同算法的公共实现。一个人

如果机器翻译需要太多的内存,那么最好是中途退却。(机器翻译直到1997年才发明。)这个生成器有一些问题,但它几乎不需要内存,几乎不需要代码,而且速度非常快。实现无处不在,Knuth的半数值算法详细介绍了这一点


要为任何RNG种子,您将需要一个熵源,请参阅(注意:因此对该链接中的()感到困惑)。这通常是由CPU可以观察到的定时事件派生的,例如击键(我想这对您不起作用)中断和数据包到达。如果实时时钟保持自己的状态,它通常是一个可接受的源,因为重新启动很少按任何顺序计时。

伪随机数生成器是最快和要求最低的w.r.t。指令集(只有移位和异或,没有乘法或除法)是Mersenne twister思想的较小变体(称为广义线性反馈移位寄存器)。Mersenne twister本身需要太多的微控制器内存

这些生成器的问题是,如果您运气不好,它们可能会生成接近零的长序列。但是,如果状态空间大小合理,并且从另一个PNRG初始化,这是不可能的

它们对于加密或赌博也不安全,智能对手可以在观察输出后预测未来状态。这是因为它们是线性的


我曾经为一个状态空间约为50个24位字的小型非标准处理器设计过这样一个生成器。我使用Diehard测试套件测试变体,直到找到一个好的。该应用程序正在为硬件测试生成随机变体。

如果硬件为用户提供了一个按钮,一个简单的技巧是计算它的时间长度按下按钮。用足够快的短计数器,你会得到一个“随机”数字。

读取计时器并用一系列位对其进行xoring/nanding/等操作将给用户一个半随机值,因为事件之间的时间间隔可能足够大,用户无法真正分辨与计时器的相关性。

您可以将种子存储到EEPROM,当设备启动时,您可以增加种子并存储它再次说明。因此,每次重新启动都会有不同的随机数。

如果您可以使pin保持浮动,则可以使用线性反馈移位寄存器生成随机数。我不确定这是一种方法,但请查看我的代码:

// This code was written for 8051 (AT89S52)
unsigned char lfsr = 231; //8 bit shift register, with the seed of 231 or '11100111b'
unsigned char input_bit, i;

void main (void) 
{
    //Setup
    P0_0 = 0; // Leave Pin 0 Port 0 floating
    uart_init(); //Initializing uart/serial communication with pc


    while (1) 
    {
        for (i = 0; i < 255; i++) 
        {
            if (P0_0 == 1) // If Pin 0.0 is HIGH
            {
                input_bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1;
                lfsr = (lfsr >> 1) | (input_bit << 7);
            }
        }
        printf_tiny("%u\n", lfsr); //Send the random number to PC
        soft_delay(65535); //Simple delay function
    } //end while (1) loop

}
//此代码是为8051(AT89S52)编写的
无符号字符lfsr=231;//8位移位寄存器,种子为231或'11100111b'
无符号字符输入\位,i;
真空总管(真空)
{
//设置
P0_0=0;//保持引脚0端口0浮动
uart_init();//初始化uart/与pc的串行通信
而(1)
{
对于(i=0;i<255;i++)
{
如果(P0_0==1)//如果引脚0.0高
{
输入位=((lfsr>>0)^(lfsr>>2)^(lfsr>>3)^(lfsr>>4))&1;

lfsr=(lfsr>>1)|(输入位你需要多少随机性?速度是这里的首要要求,还是不可预测性最重要?针对不同目标的不同应用程序,有许多不同的伪随机数生成算法。例如,游戏不需要不可预测性,而只需要生成高security加密代码。我需要速度。没有加密要求。每次重置微控制器时,我都会得到相同的随机数。我如何避免?换句话说,我如何设置随机种子?控制器上没有实时时钟?这可以作为种子。我们有RTC,但不使用它是项目明智的决定。我们模拟RT固件的C。感谢您的评论。固件的第二个计数器可以用作种子。之所以选择作为最佳答案,是因为我发现LFSR实现起来最省时,而且速度也很快。我使用静态值作为种子,因为我们的设备几乎不会被重置。当重置发生时,它是否产生相同的随机数并不重要。seed值0xAC的周期大于10^8。为正确的位模式选择正确的种子将获得最大LFSR,它将生成位模式中除0以外的所有数字。这些RNG需要一个种子才能工作。每次重置微控制器时,我都会得到相同的随机数集。啊哈,好问题。(我们向她询问基本的RNG问题