Answers:
您使用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;
}
将ADC连接到硬件噪声源,并在需要时使用软件“加白”随机数。
这是一个基于AVR的项目,它可以完成此任务:Leon的迷你便携式随机数发生器(mPRNG)
根据所需的密码安全性,您可以使用接地模拟输入或“ 内部温度传感器 ” 的噪声作为随机性种子,而不是外部硬件。
更新:后来我为Arduino编写了一个程序,该程序使用芯片的计时器作为熵源(由于嘈杂的比特被截断了,所以ADC没用),这激发了熵库的创建。
在这两种情况下,随机性都不来自温度值本身,温度值本身变化缓慢,而是来自最低有效位,最低有效位从一次读取到下一次随机变化。我多次读取该值,对于输出的每一位一次,与上一次读取进行位移和异或。 将真正的随机位与不相关的位进行XOR可以保留随机性,因此随机性会散布到所有位,从而变成真正的白噪声。但是,您的比特率不会很高,因为每个采集时间或定时器周期只能得到一位输出。使用计时器方法,我获得了约64位/秒的速度。
为了确保不会以相同的顺序重新启动,我在eeprom中使用了somme字节:
#include <avr/eeprom.h>
#include <stdlib.h> // rand
u16 EEMEM randinit;
int main(void) {
srand(eeprom_read_word(&randinit));
eeprom_write_word(&randinit,rand());
[...]
}
这样可以产生很好的随机性,并且不会在程序/内存中花费太多。
我创建了一个库,尽管最初为Arduino设计的库在avr上使用g ++在C ++实现中可以很好地用作类,但实际上它最近也已移植到ARM体系结构中。
它利用了看门狗定时器和系统时钟之间的抖动,并且已经在许多不同的芯片上进行了测试(记录在Wiki页面上)
http://code.google.com/p/avr-hardware-random-number-generation/wiki/WikiAVRentropy
您是否看过使用randomSeed()之类的东西?-在Arduino IDE中使用
您可以使用此函数对atmel AVR上的浮动(自由)模拟引脚进行采样,然后使用该值为伪随机数函数-random()创建任意起点。
random()创建的值可以是伪随机数-但是randomSeed()创建的任意起点应尽可能是真实的随机数/值。