我读过 TI ( slaa338 ) 的应用说明,它描述了一种生成“真实”(而不是“伪”)随机数的技术。它利用 MSP430 有点奇特的时钟子系统来实现这一目标。有谁知道可以在 AVR(我对 XMega 尤其感兴趣)上实现的用于生成“真实”随机数的技术?
AVR 随机数发生器
电器工程
avr
xmega
随机数
2022-01-20 09:46:18
4个回答
将 ADC 连接到硬件噪声源,并在需要时使用软件“白化”随机数。
这是一个基于 AVR 的项目:Leon's Mini Portable Random Number Generator (mPRNG)
根据它需要的加密安全程度,您可以使用接地模拟输入或“内部温度传感器”的噪声作为随机种子,而不是外部硬件。
更新:我后来为 Arduino 编写了一个程序,它使用芯片的定时器作为熵源(ADC 被证明是无用的,因为噪声位被截断),这激发了熵库的创建。
在这两种情况下,随机性都不是来自温度值本身,它只是缓慢变化,而是来自最低有效位,从一次读取到下一次读取随机变化。我多次读取该值,一次用于输出的每一位,移位和异或与前一次读取。 将真正的随机位与不相关的位进行异或会保留随机性,因此随机性会扩散到所有位,并变成真正的白噪声。但是,您的比特率不会很高,因为每个采集时间或定时器周期只能得到一位输出。使用计时器方法,我得到了大约 64 位/秒。
你使用 XMega 有多糟糕?如果加密和随机数生成是您项目的重要组成部分,Atmel 的SecureAVR系列内置硬件随机数,专为加密应用而设计。
无论如何,我怀疑你会找到一个分布良好的随机种子源。您将希望通过伪随机数生成器运行它几次只要您每次都从不同的种子开始,这将为您提供一组不错的随机数。LGC 是一种快速简便的伪随机生成器:
static unsigned long Seed;
/* Call before first use of NextVal */
unsigned long InitSeed()
{
//Your code for random seed here
// Correct distribution errors in seed
NextVal();
NextVal();
NextVal();
return NextVal();
}
/* Linear Congruential Generator
* Constants from
* "Numerical Recipes in C"
* by way of
* <http://en.wikipedia.org/wiki/Linear_congruential_generator#LCGs_in_common_use>
* Note: Secure implementations may want to get uncommon/new LCG values
*/
unsigned long NextVal()
{
Seed=Seed*1664525L+1013904223L;
return Seed;
}
生成随机种子的另一个技巧是计算外部事件之前的时钟周期数。例如,如果这是一个人使用的设备,请计算时钟周期数,直到他按下“开始”按钮,并将其用作随机种子。
为了确保不会以相同的顺序重新启动,我在 eeprom 中使用了一些字节:
#include <avr/eeprom.h>
#include <stdlib.h> // rand
u16 EEMEM randinit;
int main(void) {
srand(eeprom_read_word(&randinit));
eeprom_write_word(&randinit,rand());
[...]
}
这给出了相当好的随机性,并且在程序/内存中花费不多。