2009-10-13 17 views
7

Jak skutecznie generować liczby losowe w mikrokontrolerze? Czy są jakieś ogólne wytyczne lub konkretna szybka metoda?Jak skutecznie generować liczby losowe w mikrokontrolerze?

+2

Ile losowości potrzebujesz? Czy prędkość jest tu najważniejsza, czy najważniejsza jest nie przewidywalność? Istnieje wiele różnych algorytmów generowania liczb pseudolosowych dla różnych aplikacji o różnych celach. Gra, na przykład, nie wymagałaby nieprzewidywalności tak bardzo jak powiedzmy, czegoś generującego kody szyfrowania o wysokim poziomie bezpieczeństwa. – Amber

+0

Potrzebuję prędkości. Nie ma wymogu kryptograficznego. – Donotalo

Odpowiedz

5

Można wygenerować pseudolosowych numerów poprzez manipulowanie bitami poprzez symulowanie rejestr przesuwający z liniowym sprzężeniem zwrotnym

Kwestia staje się 'ile bitów chcesz symulować?

Wikipedia zawiera informacje.

+1

Za każdym razem, gdy mikrokontroler jest resetowany, otrzymam te same ustawione liczby losowe. Jak mogę tego uniknąć? Innymi słowy, w jaki sposób mogę ustawić losowe nasiona? – Donotalo

+2

Brak zegara czasu rzeczywistego na kontrolerze? To może działać jak nasienie. –

+0

Mamy RTC, ale jest to rozsądna pod względem projektowym decyzja, aby tego nie używać. Symulujemy RTC za pomocą oprogramowania układowego. Dziękuję za komentarz. Drugi licznik oprogramowania może być użyty jako seed. – Donotalo

4

Jeśli masz dostęp do ADC, możesz odczytać z niego najmniej znaczący bit i użyć go jako nasienia dla generatora liczb pseudolosowych, tak jak napisali inni. Oczywiście będziesz musiał przeczytać więcej niż jeden bit z ADC, więc potrzeba wielu odczytów, co może trochę potrwać. Ale wystarczy to zrobić tylko raz, na przykład przy starcie, a następnie użyć szybszego PRNG do generowania nowych liczb losowych.

Wiele wbudowanych urządzeń ma wbudowane ADC, na przykład rodzina Atmel z rodziny ATMega.

+1

Niestety ADC w ATMegas jest zbyt stabilny. Nawet LSB nie zmienia się podczas wielu odczytów. http://skemman.is/stream/get/1946/10689/25845/1/ardrand.pdf "Badamy różne metody wyodrębniania prawdziwego losowości z mikrokontrolera i dochodzimy do wniosku, że nie powinno to być wykorzystywane do produkcji losowości z jego analogowych szpilek. " – endolith

9

Zwykle generowane są liczby pseudolosowe, a nie rzeczywiste liczby losowe, chociaż obie są możliwe w różnym tempie.

Istnieją dwie ogólne kategorie, w zależności od tego, czy sekwencja będzie używana do celów kryptograficznych. Podstawowym rozróżnieniem jest to, czy znajomość jednej liczby w sekwencji umożliwia przewidywanie następnej. Ogólnego przeznaczenia RNG nie martwią się o to, czy znajomość algorytmu pozwoli obserwatorowi na skopiowanie sekwencji i przebiegają one trochę szybciej.

Typowym uniwersalnym algorytmem RNG jest Mersenne Twister. Istnieje wiele publicznych implementacji różnych algorytmów. See here dla jednego.

Jeśli MT wymaga zbyt dużo pamięci, w pół drogi przyzwoity awaryjny jest linear congruential generator. (MT nie został wymyślony do 1997 r.) Ten generator ma pewne problemy, ale prawie nie wymaga pamięci, prawie żadnego kodu i jest niezwykle szybki. Wdrożenia są wszędzie i szczegółowo omówiono je w algorytmach seminumerycznych Knuta:.

Aby zaszczepić dowolny RNG, będziesz potrzebował źródła entropii, zobacz http://en.wikipedia.org/wiki/Entropy_(computing) (Uwaga: SO denerwuje się() w tym łączu.) Jest to zazwyczaj pochodne od zdarzeń czasowych, które procesor może obserwować, takie jak jako naciśnięcia klawiszy (myślę, że to nie zadziała) przerwań i przylotów pakietów. Zegar czasu rzeczywistego jest często dopuszczalnym źródłem, jeśli zachowuje swój własny stan, ponieważ restarty rzadko mają określony czas w dowolnej kolejności.

+0

Te RNG potrzebują nasion do pracy. Za każdym razem, gdy mikrokontroler zostanie zresetowany, otrzymam ten sam zestaw liczb losowych. – Donotalo

+0

Aha, dobre pytanie. (Otrzymujemy podstawowe pytania RNG na SO przez cały czas, więc wybacz nam, że odruchowo odpaliliśmy podstawową odpowiedź :-) W każdym razie, zaktualizowałem swoją odpowiedź. Zrobię kolejną aktualizację za minutę ... – DigitalRoss

+0

Mersenne Twister używa przestrzeni stanu, która jest zbyt duża dla mikrokontrolerów. – starblue

1

Generatory liczb pseudolosowych, które są najszybszymi i najmniej wymagającymi w.r.t. zestaw instrukcji (tylko shift i xor, bez mnożenia lub dzielenia) są mniejszymi wariantami pomysłu twister Mersenne (zwanego Generalized Linear Feedback Shift register). Mersenne Twister sam potrzebuje zbyt dużo pamięci dla mikrokontrolerów.

Problem z tymi generatorami polega na tym, że mogą generować długie sekwencje w pobliżu zera, jeśli nie masz szczęścia. Przy rozsądnym rozmiarze przestrzeni stanów i inicjalizacji z innego PNRG jest to jednak mało prawdopodobne.

Nie są również bezpieczne do kryptografii lub hazardu, inteligentny przeciwnik może przewidzieć przyszłe stany po zaobserwowaniu wyniku. Jest tak, ponieważ są one liniowe.

Kiedyś zaprojektowałem taki generator dla małego niestandardowego procesora z przestrzenią stanu około 50 24-bitowych słów. Testowałem warianty z zestawem testowym Diehard, dopóki nie znalazłem dobrego. Aplikacja generowała losowe odmiany w teście sprzętowym.

2

Jeśli sprzęt ma przycisk dla użytkownika, prosta sztuczka polega na zliczaniu czasu naciśnięcia przycisku. Dzięki wystarczająco krótkiemu licznikowi otrzymujesz liczbę "losową".

+1

Czy znasz jakieś oszacowanie liczby bitów entropii, biorąc pod uwagę szybkość licznika "x" Hz? –

+0

Niestety, nie. Sądzę, że ktoś sprytny mógł to zrozumieć. –

+0

Jest to dobre rozwiązanie, ale w moim przypadku potrzebuję liczby losowej znacznie wcześniej, zanim nastąpi interakcja użytkownika (w rzeczywistości, gdy tylko mikroprocesor zostanie zasilony).Dzięki za pomysł. – Donotalo

0

Odczytywanie timera i xoring/nanding/etc z serią bitów da pół losowe dla użytkownika, ponieważ czas pomiędzy zdarzeniami jest prawdopodobnie wystarczająco duży, niezależnie od tego, że użytkownik nie będzie w stanie powiedzieć korelacja z zegarem.

8

można przechowywać materiał siewny do pamięci EEPROM, a po uruchomieniu urządzenia można zwiększyć materiał siewny i zapisać go ponownie. Tak więc przy każdym ponownym uruchomieniu będziesz miał inną losową liczbę.

0

Jeśli możesz pozostawić sworzeń unoszący się, może to pomóc w generowaniu liczb losowych z liniowym rejestrem przesuwu liniowego. Nie jestem pewien, że to jest do zrobienia, ale proszę spojrzeć na mój kodu:

// This code was written for 8051 (AT89S52) 
unsigned char lfsr = 231; //8 bit shift register, with the seed of 231 or '11100111b' 
unsigned char input_bit, i; 

void main (void) 
{ 
    //Setup 
    P0_0 = 0; // Leave Pin 0 Port 0 floating 
    uart_init(); //Initializing uart/serial communication with pc 


    while (1) 
    { 
     for (i = 0; i < 255; i++) 
     { 
      if (P0_0 == 1) // If Pin 0.0 is HIGH 
      { 
       input_bit = ((lfsr >> 0)^(lfsr >> 2)^(lfsr >> 3)^(lfsr >> 4)) & 1; 
       lfsr = (lfsr >> 1) | (input_bit << 7); 
      } 
     } 
     printf_tiny("%u\n", lfsr); //Send the random number to PC 
     soft_delay(65535); //Simple delay function 
    } //end while (1) loop 

} 

EDIT: I okazało się, moja odpowiedź może być zły. Więcej szczegółów na temat, dlaczego nie należy używać pływającego cyfrowego pin: https://electronics.stackexchange.com/questions/50476/random-number-generators-using-a-gpio-pin

Powiązane problemy