什么是随机数发生器的最小和最简单的种子?


40

一个小型微控制器(8位Atmel)控制许多灯光,以便以许多精美的随机灯光序列呈现灯光秀。

合适的伪RNG可以很好地完成其工作,但是我正在寻找一个好的种子。种子是必须的,因为如果有人同时打开多个这样的设备,那么如果它们都产生相同的效果序列,直到它们由于各自时钟源的微小差异而缓慢地分开,效果就不好了。

在必须通过按下按钮或按下开关来启动设备的情况下,可以使用一种非常好的方法来植入伪RNG,这是我经常使用的方法。µc上电后,就可以启动一个非常快速的计时器,并且第一次按下该按钮时,该计时器的值就会触发RNG。

问题是,在这种情况下,没有按钮。设备通电后,程序必须立即启动。

PCB上的位置非常有限(最多只能容纳几个最小的SMD零件),因此我正在寻找最小和最简单的解决方案。因此,我将排除真正的RNG硬件,无线电接收器等奇特的解决方案。

我所拥有的只是CPU中的16位计时器,还有一个未使用的可访问ADC的端口引脚。

我当前的解决方案是仅使用一个电阻(尽可能不准确)为ADC引脚提供大约一半的电源电压,并为RNG注入第一个AD转换值。但是,当今大多数10%的电阻器的误差都远低于1%(当我告诉他们我们想要他们能找到的质量最差的SMD电阻器时,可以想象供应商的面孔很有趣),因此,从同一种子开始的多个单元。

更好的选择是进行多次转换,并从这些测量的最低有效位中建立一个值。但是,我之前使用过这种µc类型的ADC,我知道它非常准确。以最快的速度运行ADC可能会有所帮助。

有谁有更好的建议?种子不需要完全均匀地分布,但是分布越均匀越好。一个16位种子且分布完全均匀的梦想太好了,以至于无法实现,但是我认为在5位或6位上进行中等分配可能就足够了。


12
“当我告诉他们我们想要他们能找到质量最差的SMD电阻器时,想象供应商的面孔会很有趣” –甚至在电路图中未定义该电阻器的值,​​然后告诉他们,这会更有趣。生产中的人们认为,这部分必须在PCB从贴装机中出来之后,从我们将每个电阻值混合在一起的容器中手动焊接出来。-因为不是我要寻找的RNG,而是种子。因此,如果它几乎每次都产生相同的值时还不错,那么跨设备进行区别处理就变得更加重要。
vsz 2015年

8
为什么不在生产编程期间将随机值写入EEPROM存储?这样,您可以使用自己喜欢的最高级的RNG,因为它只会出现在生产编程器中,而不会出现在最终设备中。(信用@immibis:您的“略有不同的软件文件”给了我这个主意。)
Calrion 2015年

2
因此,仅需%100清除,问题是它们可能以相同的顺序开始,而不是它们可能会随时间推移而分开,对吗?
wedstrom

2
RNG的选择很重要:有些需要优质种子,有些则不需要。例如,对于Xorshift,除0以外的任何种子都将起作用,并且将同样有效。即使初始种子的微小差异也会导致RNG循环中的起始位置发生很大变化。
curiousdannii 2015年

3
您可以将所有ADC答案与统计信息和时序结合起来,以获得更大的随机性。例如,测量直到获得N个样本(最低3个LSB为101)和M个样本(最低3个LSB为110)之前,需要花费多少处理器滴答声。根据需要扩展此概念。
wjl

Answers:


24

在A / D引脚和地面之间放置一个并联的电阻器和电容器。使电阻相当高,最好远高于A / D的输入信号阻抗要求。使RC时间常数大约为10 µs。例如,100kΩ和100 pF听起来很不错。

要获得具有一定随机性的值,请将引脚驱动一会儿,然后将其设置为高阻抗,并在几微秒后读取A / D。特别是如果您适当地滥用了A / D采集时间,它将看到的电压将取决于R和C值,引脚漏电流,附近的其他噪声和温度。

抓住低位或低两位,并根据需要重复以获取任意数量的随机位。

对于更随机的模式,请偶尔执行此过程,并将A / D结果的低位注入到您已经在使用的随机数发生器中。


听起来不错。确保检查ADC的输入阻抗-Atmega8系列的模拟输入阻抗为100Meg,这会使Olin的电阻值有点低。
stefandz

3
@stef:正确转换所需的输入阻抗和信号阻抗是两个不同的东西。是的,由于是CMOS,因此输入阻抗很高。但是,信号上有一个最大阻抗限制,以使其能够在指定的时间内为样品充电并固定帽,并克服引脚可能发生的任何泄漏。
奥林·拉斯特罗普

2
抱歉,根据您的回答,我认为您是在参考输入阻抗,而不是源阻抗规范。10k是Atmega8规定的最大源阻抗,因此您可以找到答案。作为参考,如果有人有兴趣,内部的S / H上限为14pF。
stefandz

2
@stef:我编辑了答案以使其更清楚。
奥林·拉斯洛普

您错过了农历和银行假期。还要用手挥舞有用的附加物,尤其是在低C且屏蔽效果不好的情况下。
罗素·麦克马洪

23

一些可能的选择:

  1. 为每个设备预编程一个唯一的串行地址。如果您有足够好的RNG算法,那么即使是序列地址的顺序列表也会产生截然不同的结果。

  2. 根据您的MCU /设置,您可能有两个不同的时钟源可用于系统时钟和看门狗定时器/计时器计数器输入。如果其中一个/两个都有很大的差异,则可以使用它来生成适当不同的种子。这是我编写的示例,该示例使用Arduino的内部看门狗定时器和外部XTAL系统时钟

  3. 使用BJT晶体管并构建高度依赖β的放大器。可以从ADC读取该种子。

  4. 电容器/电感器的额定公差通常比电阻器差得多。您可以使用它们构建某种滤波电路(RC,RL,LC),并使用ADC测量输出。


5
我为选项1投票,它是零零件数解决方案,将导致序列不必匹配。序列号和RND生成器可以说16位,使得任何设备模仿他人模式的机会都可以忽略不计。
KalleMP

1
我也喜欢解决方案之一。如果您使用简单的哈希算法,即使您有序列号也可以。
magu_

6
关于选项1的一件好事是,某些设备带有内置的序列号(通常是与网络/ RF相关的Micros),因此您甚至不需要单独的步骤即可刻录序列号
slebetman 2015年

3
甚至像LCG这样的垃圾RNG 也会“为串行地址的顺序列表产生截然不同的结果”。我也投1票。
BlueRaja-Danny Pflughoeft 2015年

3
如果您有时间源,那么将其用作切换种子的基础将有助于抵消运行之间的影响。如果您的设备有一个,则将其与序列号/编号或MAC地址结合使用,您也将修复设备间的匹配。我见过一些软件,即使重新启动后,该软件仍会永久存储所生成的一些或每个随机数作为种子。如果您的设备具有不同的工作时间,则它们应分开放置。
TafT

8

未初始化的内存

您可以尝试使用微控制器中的未初始化内存。诀窍是找到具有最“平衡”触发器且实际上是随机的位。该过程是读取所有内存,重置并重复几次以测量哪些位是真正随机的。然后,您可以使用此映射读出足够的随机位来为PRNG或LFSR注入种子!

即使使用相同的硬件,此方法也应为您提供随机的种子,此每日hack 文章中提供了更多详细信息(和链接)

我喜欢这种方法,因为它不需要任何其他电路或引脚。您的AVR已经装有内存,您只需要查找不稳定(随机)位即可。映射过程也可以自动化。您可以对每个设备应用相同的代码和过程,并获得真正的随机结果!


1
您实际上不需要弄清楚哪些位是随机的。即使只有8位是随机的,对所有字节进行XOR运算也会给您带来随机的结果。如图所示,实际值在时间上可能不是随机的,它们足够独特-这正是我们在此需要的。
MSalters

1
如果找到允许您“混合”熵的PRNG,那么它可能比XOR-then-seed选项更好。遍历未初始化的内存,然后将字节混入PRNG。例如,请参阅我的simplerandom C库-mix函数
Craig McQueen

这不会给您带来加密质量的随机性。

@CamilStaps当然不会。
纳文2015年

1
这是行不通的。如果我有一个操作系统,并且无法控制将哪部分内存分配给我的程序以及之前的内容,则未初始化的内存是未定义的行为。在没有操作系统的微控制器上,情况并非如此。特别是对于AVR,因为如果经过了足够的时间以使掉电时的电流消耗耗尽电容器,那么所有RAM都将为零。
vsz 2015年

7

对于具有随机功能的MP3播放器,我所做的就是在每次开机时都使用不同的顺序种子。我从1开始并将其存储在EEPROM中,以便在下一次上电时我使用2等等。这是在ATMEGA168上。正如helloworld922所指出的,即使是简单的顺序种子也将生成完全不同的伪随机序列。

我使用了线性一致随机序列生成器之一,它给出了均匀分布。

int i;
seed = seed * 2053 + 13849;
i = (seed % max) + 1;  // max is the maximum value I want out of the function

当然,如果您希望多个单元具有不同的顺序,即使它们可能具有相同的电源循环次数,那么您就需要随机开始一些操作。

这可以通过其他张贴者提出的任何方法来完成-我想到的一种方法可以使用交流过零(如果有的话)进入处理器(例如用于灯相位控制)?这可用于在加电后的第一个穿越时对计时器进行采样,然后用作种子。

设备上是否有任何按钮可以选择模式等?如果是这样,您可以在对MCU进行编程后第一次按下按钮时对计数器进行采样,您可以首先生成随机种子并将其存储在EEPROM中。此后的每次加电将使用存储的种子。


5

ADC是很好的随机性来源。

您无需依靠电阻公差。任何电阻都会产生热噪声,并且在执行所有采样和转换步骤时,相同的物理效应会将噪声引入ADC。(数据表将告诉您有关噪声的数量以及最差/最佳的配置设置。)

您不应将ADC引脚悬空;这可能会使电压浮动太大,并有使输入饱和的风险。
(许多MCU允许您使用大约一半的电源电压作为ADC输入进行校准。这节省了外部电阻,并且仍然给您带来噪声。同样,请参见数据表以了解最差/最好的配置。)

您无需依赖单个ADC测量;您可以将多个测量结果与一个简单的哈希或校验和函数结合在一起(CRC就足够了)。如果需要立即开始使用RNG,则可以稍后将ADC结果与当前RNG种子合并。


2
我不确定约翰逊噪声是否适合该应用;在STP上,超过10kHz带宽的10Meg电阻具有40uVJohnson噪声。您需要一个> 14位ADC或放大器电路来合理地进行测量。
helloworld922

STP并不真正相关。特别是可以有意地提高温度,但比STP高60度只是噪声的10%。
MSalters 2015年

1
一种类似的方法是在二极管中使用散粒噪声。en.wikipedia.org/wiki/Noise_generator#Shot_noise_generators
teambob

2

您可以保存会话之间的种子吗?如果是这样,是否在创建后的某个随机时间段内打开每个单元是否可行?这样一来,所有装置都将带有预设的种子,这些种子不太可能是相同的。

另一个想法:如何将多个单元链接在一起,以便它们同时打开?如果它们是串联的,则添加某种电容器,以便第(n + 1)个器件在第n个器件之后的几个时钟周期开始。理想情况下,电容器在设备关闭时会非常快速地放电,因此每次启动/重新启动之间,序列之间的间隔都更大。

如果它们是并行的,您仍然可以稍微调整启动时间。我假设使用电容器进行某种功率滤波。如果这样,则制造具有稍微不同的过滤电路的设备将导致每个设备在稍有不同的时间启动,从而在多次重启后引起发散。

对此的一种变化是在可能的情况下增加时钟信号的方差。时钟速度相差0.1%可能对灯光秀影响不大,同时会很快更改遍历PRNG表的速率。


1
也许将大量的液体倒入引脚,然后读取“主电源嗡嗡声”,以播种RNG。
2015年

1
@Jasen,连接到同一扩展导线的所有单元将看到相同的电源嗡嗡声。
伊恩·林罗斯

2

如果您在内部“校准”时钟源上运行。过一会儿后不能保存种子,最好将其保存到EEPROM中。时钟会漂移,并且会因设备而异。要在一段时间后(可能是每10分钟左右,或者在足够短的时间内(在设备正常开机时间内)发生一次)保存新值。设备开机时间越长,保存的可能性就越大EEPROM中的“不同”值。

还不时跳一次(不经常),并在设备开启时重新播种(将此新值保存在EEPROM中)。


2

通过添加LDR或热敏电阻来扩展您基于可变电阻器进行AD转换的原始想法该怎么办?(第一个设备必须能够“向外看”,我不知道这是否可行;但是光线的变化可能要比大约在同一时间在同一地点启动的设备之间的温度变化要大。 ..)


1
热敏电阻具有另一个有用的特性。大多数制造商的几个系列差异很大且不准确。这将进一步“改善”结果。
Ariser 2015年

1

2种潜在解决方案,均假设您需要每单位唯一的种子。

  1. 如果您在工厂中逐个刷新单元,则可以通过编程器中的某些中间脚本以编程方式修改十六进制文件。如果是PC控制的,则可以使用日期和时间覆盖变量初始化。保证每个单元都是唯一的!

  2. 达拉斯1线设备仅使用一个引脚,每个引脚都具有唯一的64位序列号。您可以将其用作种子。


1
我喜欢2,但不幸的是DS零件都相当昂贵。
Ariser

不要将生产时间戳用于加密质量随机性,这是可以预见的。

2
@CamilStaps对于OP的应用程序,不需要加密品质
哈根·冯·艾特森

1
@HagenvonEitzen是正确的,但是其他人可能会在这个问题上寻求加密Q随机性,因此值得一提。

4
@CamilStaps 叹息,看来您已经放弃了人类:)是否真的太过苛刻,以至于希望出于电子目的将使用electronicSE的答案用于加密目的的某人期望他们至少足够小心才能读懂应该回答的问题?即使由一群Schrödinger猫产生,“ 16bit”或“ 5 o5 6 bit”种子也不是crypto-Q的。)
Hagen von Eitzen 2015年

1

您可以保留一个浮动ADC引脚,以将捕获的噪声馈入随机数发生器(RNG)。它足以生成一个种子,甚至可以用作RNG生成器。

不要忘记使用最少的转换时间。

另一种解决方案是将噪声发生器应用于ADC引脚。


2
我将进行一些测量,但是如果我没有记错的话,一个浮动的ADC引脚将读取0或接近0。我会再次检查以查看情况是否如此。
vsz 2015年

1
我很感兴趣,0浮动时会读吗?
Bence Kaulics'9

2
问题在于,这可能在开发板上起作用,并且最终产品失败。
vsz 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.