題:
隨機數生成器的最小和最簡單的種子是什麼?
vsz
2015-09-02 21:21:55 UTC
view on stackexchange narkive permalink

一個小型微控制器(8位Atmel)控制許多燈光,以呈現具有許多精美隨機燈光序列的燈光錶演。

一個合適的偽RNG可以很好地完成其工作,但是我正在尋找一個好的種子。種子是必須的,因為如果有人同時打開多個這樣的設備,那麼如果它們都產生了相同的效果序列,直到它們由於各自的時鐘源的微小差異而緩慢地分開,效果就不好了。 / p>

對於我必須經常使用的偽RNG種子,一種非常好的方法是可能的,如果該設備必須通過按下按鈕或按下開關來啟動。 µc上電後,就可以啟動一個非常快速的計時器,並且第一次按下該按鈕時,該計時器的值就會觸發RNG。

問題是,在這種情況下,沒有按鈕。該程序必須在設備加電後立即啟動。

PCB上的位置非常有限(最多只能容納幾個最小的SMD零件) ),因此我正在尋找最小,最簡單的解決方案。因此,我將排除像真正的RNG硬件,無線電接收器之類的奇特解決方案。

我所擁有的只是CPU中的一個16位計時器,還有一個未使用的可訪問ADC的端口引腳。

我當前的解決方案是僅使用一個電阻(盡可能不准確)為ADC引腳提供大約一半的電源電壓,並為RNG注入第一個AD轉換值。但是,如今大多數10%的電阻器的誤差都遠低於1%(當我告訴他們我們想要他們能找到的質量最差的SMD電阻器時,想像供應商的面孔會很有趣),因此,同一種子開始的多個單位。

更好的選擇是進行多次轉換,並從這些測量的最低有效位中建立一個值。但是,我之前使用過這種µc類型的ADC,我知道它非常準確。以最快的速度運行ADC可能會有所幫助。

有人有更好的建議嗎?種子不需要完全均勻地分佈,但是分佈越均勻越好。一個16位種子且分佈完全均勻的夢想太好了,以至於無法實現,但是我認為在5位或6位上進行一半的體面分配可能就足夠了。

“當我告訴他們我們想要他們可以找到質量最差的SMD電阻器時,想像一下供應商的面貌會很有趣” –甚至在電路圖中未定義該電阻器的值,並告訴他們生產中的人們認為,這部分必須在PCB從貼裝機中出來後,從我們將每個電阻值混合在一起的容器中手動焊接出來。-因為它不是我要尋找的RNG,而是*種子*。因此,如果它幾乎每次都產生相同的值時還不錯,那麼跨設備進行區別處理就變得更加重要。
實際上,在藝術音樂中已經有意地探索了“緩慢漂移”的部分,例如史蒂夫·里奇(Steve Reich)的“GyörgyLigeti-100首節律詩的交響曲”或“鋼琴階段”。
您可以使用略有不同的軟件文件對每個uC進行編程嗎?
有什麼原因不能使ADC引腳懸空並從中讀取值?也許減去一個量然後乘以放大誤差?
為什麼不在生產編程期間將隨機值寫入EEPROM存儲?這樣,您可以使用自己喜歡的最高級的RNG,因為它只會出現在生產編程器中,而不會出現在最終設備中。(向@immibis:授予您“略有不同的軟件文件”的想法)。
有點含糊的“ 8 bit atmel”:AVR系列?8051系列?其他?
@Calrion這就是我的想法。
同樣,您可以將一些快速的東西(例如時鐘或總線或其他東西)連接到ADC,無論是否帶有外部RC濾波器(輸入將具有一些內置濾波器和/或寄生參數),並從中提取位那。
因此,僅需%100清除,問題是它們可能以相同的順序開始,而不是它們可能會隨時間推移而分開,對嗎?
RNG的選擇很重要:有些需要優質種子,有些則不需要。例如,對於Xorshift,除0以外的任何種子都將起作用,並且將同樣有效。即使初始種子的微小差異也會導致RNG循環中的起始位置發生很大變化。
您可以將所有ADC答案與統計信息和時序結合起來,以獲得更大的隨機性。例如,測量直到獲得N個樣本(最低3個LSB為101)和M個樣本(最低3個LSB為110)所花費的處理器滴答次數。根據需要擴展此概念。
4.必填xkcd漫畫:[鏈接] https://xkcd.com/221/
[相關。](https://electronics.stackexchange.com/questions/50476/random-number-generators-using-a-gpio-pin)
十 答案:
helloworld922
2015-09-02 22:00:09 UTC
view on stackexchange narkive permalink

一些可能的選項:

  1. 為每個設備預編程一個唯一的串行地址。如果您有足夠好的RNG算法,那麼即使是連續的序列地址列表也會產生截然不同的結果。

  2. 根據您的MCU /設置,您可能會有兩個不同的時鐘源可用於系統時鐘和看門狗定時器/計時器計數器輸入。如果其中一個/兩個都有很大的差異,則可以使用它來生成適當不同的種子。 這是我寫的一個示例,該示例使用Arduino的內部看門狗定時器和外部XTAL系統時鐘

  3. 使用BJT晶體管並構建一個高度beta版本依賴放大器。可以從ADC讀取種子信息。

  4. 電容器/電感器的容差通常比電阻器差得多。您可以使用它們構建某種濾波器電路(RC,RL,LC),並使用ADC測量輸出。

  5. ol>
我為選項1投票,它是零零件數解決方案,將導致序列不必匹配。序列號和RND生成器可以說16位,使得任何設備模仿他人模式的機會都可以忽略不計。
我也喜歡解決方案之一。如果您使用簡單的哈希算法,則即使有序列號也沒問題。
關於選項1的一件好事是,某些設備帶有內置的序列號(通常是與網絡/ RF相關的micros),因此您甚至不需要單獨的步驟即可刻錄序列號
甚至像[LCG](https://en.wikipedia.org/wiki/Linear_congruential_generator)之類的垃圾RNG也會_“對於序列地址的順序列表產生截然不同的結果” _。我也投1票。
如果您有時間源,那麼將其用作切換種子的基礎將有助於抵消運行之間的影響。如果您的設備有一個,則將其與序列號/編號或MAC地址結合使用,您也將修復設備間的匹配。我見過一些軟件,即使重新啟動後,該軟件仍會永久存儲所生成的一些或每個隨機數作為種子。如果您的設備具有不同的工作時間,則它們應分開放置。
+1,用於使用預編程的序列號作為種子。
@BlueRaja-DannyPflughoeft對,甚至[RANDU](https://en.wikipedia.org/wiki/RANDU)!
我喜歡選項2,因為它不需要任何外部硬件,除了外部振盪器。但是,如果我使用內部振盪器作為時鐘源,它將無法正常工作。
這取決於MCU。例如,ATmega1280的看門狗定時器有一個獨立的內部振盪器,而不是系統時鐘使用的內部振盪器。但是,由於它們是在同一模具上製造的,因此實際上很難說出多少不同。
Olin Lathrop
2015-09-02 22:15:23 UTC
view on stackexchange narkive permalink

在A / D引腳和地之間放置一個並聯的電阻和電容。使電阻相當高,最好遠高於A / D的輸入信號阻抗要求。使RC時間常數大約為10 µs。例如,將100kΩ和100 pF聽起來是一個很好的組合。

要獲得具有一定隨機性的值,請將引腳拉高一會兒,然後將其設置為高阻抗並進行A / D讀取幾微秒後。特別是如果您適當地濫用了A / D採集時間,它將看到的電壓將取決於R和C值,引腳洩漏電流,其他附近的噪聲和溫度。

抓住低位或低兩位,並根據需要重複以獲得任意數量的隨機位。

對於更隨機的模式,請偶爾執行此過程,並將A / D結果的低位注入隨機數生成器您已經在使用。

聽起來不錯。確保檢查ADC的輸入阻抗-Atmega8系列的模擬輸入阻抗為100Meg,這會使Olin的電阻值有點低。
@stef:正確轉換所需的輸入阻抗和信號阻抗是兩件事。是的,由於是CMOS,因此輸入阻抗非常高。但是,信號上有一個最大阻抗限制,以使其能夠在指定的時間內為樣品充電並固定帽,並克服引腳可能發生的任何洩漏。
抱歉,根據您的回答,我認為您是在參考輸入阻抗,而不是參考源阻抗規範。10k是Atmega8規定的最大源阻抗,因此您可以找到答案。作為參考,如果有人有興趣,內部的S / H上限為14pF。
-1
您錯過了農曆和銀行假期。還可以用手揮舞一下有用的附加物,尤其是在C較低且屏蔽不好的情況下。
esoterik
2015-09-03 03:19:32 UTC
view on stackexchange narkive permalink

未初始化的內存

您可以嘗試在微控制器中使用未初始化的內存。訣竅是找到具有最“平衡”觸發器且實際上是隨機的位。該過程是讀取所有內存,重置並重複幾次以測量哪些位是真正隨機的。然後,您可以使用該映射表讀出足夠的隨機位來為PRNG或LFSR注入種子!

即使使用相同的硬件,此方法也應為您提供隨機種子,此hack中提供了更多詳細信息(和鏈接)每天 article

我喜歡這種方法,因為它不需要任何其他電路或引腳。您的AVR已經裝有內存,您只需要查找不穩定(隨機)位即可。映射過程也可以自動化。您可以對每個設備應用相同的代碼和過程,並獲得真正的隨機結果!

您實際上不需要弄清楚哪些位是隨機的。即使只有8位是隨機的,對所有字節進行異或運算也會給您帶來隨機的結果。如圖所示,實際值在時間上可能不是隨機的,它們足夠獨特-這正是我們在此需要的。
如果您找到一個PRNG可以“混合”熵,那麼它可能比XOR-then-seed選項更好。遍歷未初始化的內存,然後將字節混入PRNG。例如。參見我的[simplerandom C庫-混合函數](https://github.com/cmcqueen/simplerandom#mix-function)。
這不會給您帶來加密質量的隨機性。
@CamilStaps當然不會。
這是行不通的。如果我有一個操作系統,並且無法控制將哪部分內存分配給程序以及之前的內容,則未初始化的內存是未定義的行為。在沒有操作系統的微控制器上不是這種情況。特別是對於AVR,因為如果經過了足夠的時間以使掉電時的電流消耗耗盡電容器,那麼所有RAM都將為零。
@vsz不,某些位在加電時是隨機的。試試看。
@vsz在啟動時,某些位是“穩定的”,並且始終是相同的,其他位是“不穩定的”,並且是隨機的,這就是為什麼必須初始化內存的原因。您可以測量哪些位是隨機的,哪些不是,這些隨機位的電路更加平衡,因此隨機以1或0開頭。另外,AVR使用SRAM(即觸發器)而不是DRAM(即需要電容器刷新)。是的,在某些復位邊緣情況下,在掉電期間柱塞不會復位;你說的相反!
Kevin White
2015-09-03 01:04:37 UTC
view on stackexchange narkive permalink

我為具有隨機功能的MP3播放器所做的就是在每次開機時都使用不同的順序種子。我從1開始並將其存儲在EEPROM中,以便在下一次上電時我使用2等。這在ATMEGA168上。正如helloworld922所指出的那樣,即使是簡單的順序種子也將生成完全不同的偽隨機序列。

我使用了線性一致隨機序列生成器之一,它給出了均勻的分佈。

  int i;種子=種子* 2053 + 13849; i =(最大種子%)+1; // max是我要從函數中獲得的最大值 

當然,如果您希望多個單元具有不同的順序,即使它們可能具有相同的電源循環次數,那麼您需要可以隨機開始的東西。

這可以通過其他張貼者提出的任何方法來完成-我想到的一種方法是使用交流過零進入處理器(如果有的話)例如燈的相位控制)?可以用來在加電後的第一個穿越時對計時器進行採樣,然後用作種子。

設備上是否有任何按鈕可以選擇模式等?如果是這樣,您可以在對MCU進行編程後第一次按下按鈕時對計數器進行採樣,您可以首先生成一個隨機種子並將其存儲在EEPROM中。此後每次上電都會使用存儲的種子。

CL.
2015-09-02 21:59:31 UTC
view on stackexchange narkive permalink

ADC是很好的隨機性來源。

您不必依賴電阻的容差,任何電阻都會產生熱噪聲,並且具有相同的物理效果在執行所有採樣和轉換步驟時,會將噪聲引入ADC。 (數據手冊將告訴您有關噪聲的數量以及最差/最佳的配置設置。)

您不應將ADC引腳懸空;否則,ADC引腳將懸空。這可能會使電壓浮動得過大,並有使輸入飽和的風險。
(許多MCU允許您將電源電壓的一半用作ADC輸入,以進行校準。這可以節省外部電阻,但仍然可以給您再次,請參見數據表以了解最差/最好的配置。

您無需依賴單個ADC測量;也無需依賴於ADC。您可以通過簡單的哈希或校驗和函數將多個測量結果結合在一起(CRC就足夠了。如果您需要立即開始使用RNG,可以稍後將ADC結果與當前的RNG種子結合起來。

我不確定約翰遜噪聲是否適合該應用;在STP上,帶寬為10kHz的10Meg電阻具有Johnson噪聲為40uV。您需要一個> 14位ADC或放大器電路來合理地進行測量。
STP並不真正相關。特別是可以有意地提高溫度,但比STP高60度只是噪聲的10%。
一種類似的方法是在二極管中使用散粒噪聲。https://zh.wikipedia.org/wiki/Noise_generator#Shot_noise_generators
MichaelS
2015-09-03 10:39:31 UTC
view on stackexchange narkive permalink

您可以保存會話之間的種子嗎?如果是這樣,在創建時在某個隨機時間段內打開每個單元是否可行?這樣一來,所有單元都將附帶不太可能相同的預設種子。

另一個想法:如何將多個單元鏈接在一起,以便它們同時打開?如果它們是串聯的,則添加某種電容器,以便第(n + 1)個器件在第n個器件之後的幾個時鐘週期開始。理想情況下,電容器在設備關閉時會非常迅速地放電,因此每次啟動/重啟時序列之間的間隔都更大。

如果它們是並聯的,您仍然可以稍微隨機化啟動時間。我假設使用電容器進行某種功率濾波。如果是這樣,則製造具有稍微不同的濾波電路的設備將導致每個設備在稍有不同的時間啟動,從而導致多次重啟後產生差異。

對此的一種變化是,如果可能的話,會增加時鐘信號的差異。時鐘速度相差0.1%可能不會對燈光效果產生太大影響,同時會很快更改遍歷PRNG表的速率。

也許將大量的液體倒入引腳,並讀取一些“主嗡嗡聲”以播種RNG。
@Jasen,連接到同一擴展導線的所有單元將看到相同的電源嗡嗡聲。
Mats
2015-09-03 12:09:29 UTC
view on stackexchange narkive permalink

如果在內部“校準”時鐘源上運行。一段時間後,您是否不能保存種子,最好將其保存到EEPROM中。時鐘會漂移,並且會因設備而異。要在一段時間後(可能是每10分鐘左右,或者經過一段短短的時間以在設備的正常開機時間內發生)保存新值。設備打開的時間越長,保存的可能性就越大

也偶爾(不經常)跳一次,並在設備開啟時重新播種(將該新值保存在EEPROM中)。

Hagen von Eitzen
2015-09-05 21:53:03 UTC
view on stackexchange narkive permalink

通過添加LDR或熱敏電阻來擴展基於可變電阻器的AD轉換的原始想法怎麼樣? (首先需要能夠“向外看”,我不知道這是否可行;但是光線的變化可能要比大約在同一時間在同一地點啟動的設備之間的溫度變化要高。 ..)

熱敏電阻具有另一個有用的特性。大多數製造商的幾個系列差異很大且不准確。這將進一步“改善”結果。
jnk0le
2015-09-02 21:35:21 UTC
view on stackexchange narkive permalink

您可以保留一個浮動ADC引腳,以將捕獲的噪聲饋入隨機數發生器(RNG)。生成種子甚至將其用作RNG生成器都應該足夠。 s>

不要忘記使用盡可能短的轉換時間。

另一種解決方案是將噪聲發生器應用於ADC引腳。

我將進行一些測量,但是如果我沒有記錯的話,一個浮空的ADC引腳將讀取為“ 0”或接近於“ 0”。我會再次檢查以查看情況是否如此。
我很感興趣,浮動時它讀為0嗎?
問題在於,這可能在開發板上起作用,並且最終產品失敗。
Loganf
2015-09-03 01:24:35 UTC
view on stackexchange narkive permalink

2個潛在的解決方案,都假設您需要每個單位一個唯一的種子。程序員中的一些中間腳本。如果是PC控制的,則可以使用日期和時間覆蓋變量初始化。保證每個單元都是唯一的!

  • 達拉斯1線設備僅使用一個引腳,每個設備都具有唯一的64位序列號。您可以將其用作種子。

  • ol>
    我喜歡2,但不幸的是DS零件都很貴。
    不要將生產時間戳用於加密質量隨機性,這是可以預見的。
    @CamilStaps對於OP的應用程序,不需要加密質量
    @HagenvonEitzen是正確的,但其他人可能會在這個問題上尋求加密Q隨機性,因此值得一提。
    @CamilStaps *長嘆*,看來您已經放棄了人類:)真的真的太過期望別人想要出於加密目的而使用electronicSE的答案嗎?回答?即使由一堆Schrödinger貓產生的“ 16bit”或“ 5 o5 6 bit”種子也不是crypto-Q :)
    @HagenvonEitzen的問題太多了,無法澄清。在寫這樣的答案時,我總是會提到它。好吧...
    我應該編輯答案嗎?我想認為正在尋找加密質量隨機性的人們將能夠認識到這種區別。


    該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
    Loading...