随机数是什么
在我的理解中,随机数就是一个随机的数。这是数学上的概念。但是在编程中随机数是什么样子的呢?随机数可以通过一些函数产生但是产生的随机数都是伪随机数,这里就涉及到了一些。概念比如什么是伪随机数?
随机数的分类
随机数分为伪随机数和真随机数。
弱随机数
特点是通过纯软件算法,按照一定的规律生成一个随机值。但从名称即可看出,该类随机数的特点是只具备一定的随机性,并不能做到不可预测性,即并不是一个真正的随机数。例如通过MCU的时间作为种子去生成一个随机数,因为时间是不停变化的变量,所以生成的随机数也不停变化。但时间的变化终究有规律可循。一般这个伪随机数的序列比较长我们认为其实随机数。
强随机数
顾名思义,该类随机数具有更强的随机数特性,能够满足随机性和不可推测特性。例如通过获取敲击键盘的数据作为随机数种子进而生成一组强伪随机数,因为击打键盘存在不确定性,所以生成的随机数也更接近与真正的随机数。
什么是真随机数
真随机数同时具备随机性、不可推测和不可重复这3个基本特点。任何人无法通过软件算法或其他方法得知下一个随机数(或者随机数下一位)是什么。真随机数的生成是基于物理现象完成的,例如掷骰子、抛硬币等等。对于嵌入式行业来讲,真随机数是需要借助硬件随机数发生器来产生的。
什么是随机数发生器
随机数发生器可分为真随机数发生器、伪随机数发生器。向下又可细分为硬件真随机数发生器、硬件伪随机数发生器等。这其中只有硬件真随机数发生器对于嵌入式系统应用才是真正安全有效的。加密芯片属于电子元器件,其运行过程中会产生高斯白噪声,以其作为信息熵资源,产生真随机数。LKT加密芯片符合国际 FIPS-140-2 随机数测试标准。具有高效、资源占用少,生成随机数可靠等优点。可供用户放心使用。
以上知识参考链接为百度
随机数在密码学中的作用(一)(随机数分类介绍)
https://tieba.baidu.com/p/6768538665
STM32的真随机数(RNG)发生器
为什么说它是真随机数发生器呢?因为它的随机信号就是来源于模拟信号的转换结果这个模拟信号是随机的噪声,所以这种随机数更具有实际意义
RNG发生器如何使用
随机数发生器采用模拟电路实现。此电路产生馈入线性反馈移位寄存器 (RNG_LFSR) 的种子,
用于生成 32 位随机数。该模拟电路由几个环形振荡器组成,振荡器的输出进行异或运算以产生种子。 RNG_LFSR 由专用时钟 (PLL48CLK) 按恒定频率提供时钟信息,因此随机数质量与 HCLK 频率无关。当将大量种子引入 RNG_LFSR 后, RNG_LFSR 的内容会传入数据寄存器 (RNG_DR)。
同时,系统会监视模拟种子和专用时钟 PLL48CLK。状态位( RNG_SR 寄存器中)指示何时
在种子上出现异常序列,或指示何时 PLL48CLK 时钟频率过低。检测到错误时生成中断。
手册提到产生的数据最终会放到数据寄存器中去,根据RNG_SR状态寄存器的状态可以明白RNG器件的状态
RNG_SR的一些状态是怎样的
状态寄存器能放映是否有错,错误类型是什么,如果是种子错误那么对应的位就是1当然如果中断使能的话也会触发中断,如果是时钟错误那么对应的位就是1如果使能了中断也会触发中断,还有一个是描述错误种子的当前状态的,如果有错误但是已经及时恢复就是0,如果有错误并且恢复不了那就是1分别是种子的状态和时钟的状态,其实我们使用随机数发生器我们主要是用来让其产生我们想要的数据
也就是说我们更关心数据有没有就绪如果就绪我们就可以拿走使用如果没有就绪那就是不能使用。
如何让RNG工作并拿到随机数
把对应的寄存器进行配置后RNG方可产生随机数
#include "rng.h"
#include "delay.h"
uint8_t RNG_Init(void)
{
uint16_t Count = 0;
RCC->AHB2ENR |= (0x1<<6);//打开RNGCLK_EN
RNG->CR |= (0x1<<2);//开启RNGEN
RNG->CR |= (0x1<<3);//开启RNGIE 开了但是没有用 相当于错误导致中断不予理睬
while(!(RNG->SR & RNG_FLAG_DRDY))
{
Count++;
Delay_nus(100); //如果一直就绪不了发生超时返回失败
if(Count>10000)
{
return 0;//失败
}
}
return 1;
}
uint32_t Get_RandomNumber(void)
{
while(!(RNG->SR & RNG_FLAG_DRDY)); //检查随机数数据是否就绪 就绪可以拿数据
return RNG->DR;
}
int32_t Get_RandomRange(int min,int max)
{
return (int32_t)(min + Get_RandomNumber()%(max - min + 1)); //封装一个介于min 到max 之间的函数
}
void HASH_RNG_IRQHandler(void)
{
}
实验现象产生1-6的真随机数(模拟骰子的六个方向)
#ifndef __RNG_H_
#define __RNG_H_
#include "stm32f4xx.h"
#define RNG_FLAG_DRDY ((uint8_t)0x0001) /*!< Data ready */
#define RNG_FLAG_CECS ((uint8_t)0x0002) /*!< Clock error current status */
#define RNG_FLAG_SECS ((uint8_t)0x0004) /*!< Seed error current status */
uint8_t RNG_Init(void);
uint32_t Get_RandomNumber(void);
int32_t Get_RandomRange(int min,int max);
#endif
random32bit = 3
random32bit = 1
random32bit = 1
random32bit = 5
random32bit = 0
random32bit = 5
random32bit = 3
random32bit = 3
random32bit = 0
random32bit = 2
random32bit = 3
random32bit = 4
random32bit = 4
random32bit = 6
random32bit = 4
random32bit = 6
random32bit = 5
random32bit = 3
random32bit = 3
random32bit = 1
random32bit = 5
random32bit = 5
random32bit = 0
random32bit = 0
random32bit = 2
random32bit = 5
random32bit = 5
random32bit = 6
random32bit = 5
random32bit = 0
random32bit = 6
random32bit = 2
random32bit = 4
random32bit = 5
random32bit = 4
random32bit = 0
random32bit = 1
上面结果是通过定时调用随机数发生函数实现的现象,比如有了这个随机序列我们就可用单片机做有个按键骰子游戏。