Как эффективно генерировать случайные числа в микроконтроллере?

Как эффективно генерировать случайные числа в микроконтроллере? Существуют ли какие-либо общие рекомендации или конкретный быстрый метод?


person Donotalo    schedule 13.10.2009    source источник
comment
Сколько случайности вам нужно? Здесь превыше всего скорость или важнее непредсказуемость? Существует множество различных алгоритмов генерации псевдослучайных чисел, предназначенных для разных приложений с разными целями. Игра, например, не нуждалась бы в непредсказуемости так сильно, как, скажем, в чем-то, генерирующем высокозащищенные шифровальные коды.   -  person Amber    schedule 13.10.2009
comment
Мне нужна скорость. Криптографических требований нет.   -  person Donotalo    schedule 13.10.2009


Ответы (8)


Вы можете генерировать псевдослучайные числа, манипулируя битами, имитируя РЕГИСТР СМЕЩЕНИЯ ЛИНЕЙНОЙ ОБРАТНОЙ СВЯЗИ.

Тогда возникает вопрос: «Сколько битов вы хотите смоделировать?»

В Википедии есть некоторая информация.

person pavium    schedule 13.10.2009
comment
Каждый раз, когда микроконтроллер сбрасывается, я получаю одинаковые наборы случайных чисел. Как я могу этого избежать? Другими словами, как я могу установить случайное начальное число? - person Donotalo; 13.10.2009
comment
На вашем контроллере нет часов реального времени? Это может действовать как семя. - person Will Hartung; 13.10.2009
comment
У нас есть RTC, но не использовать его — это проектное решение. Мы моделируем RTC прошивкой. Спасибо за комментарий. Второй счетчик прошивки можно использовать как начальное значение. - person Donotalo; 13.10.2009
comment
Выбран как лучший ответ, потому что я обнаружил, что LFSR требует меньше времени для реализации, а также быстро. Я использую статическое значение для использования в качестве начального значения, потому что наши устройства вряд ли будут сброшены. Когда происходит сброс, не имеет значения, выдает ли он одинаковые случайные числа. Начальное значение 0xAC дает период более 10 ^ 8. - person Donotalo; 13.10.2009
comment
Выбор правильного начального числа для правильного битового шаблона даст вам максимальный LFSR, который будет генерировать все числа в битовом шаблоне, кроме 0. - person plinth; 13.10.2009

Обычно генерируются псевдослучайные числа, а не фактические случайные числа, хотя оба варианта возможны с разной скоростью.

Есть две общие категории, в зависимости от того, будет ли последовательность использоваться в криптографических целях. Основное различие заключается в том, позволяет ли знание одного числа в последовательности предсказывать следующее. RNG общего назначения не беспокоятся о том, позволит ли знание алгоритма наблюдателю продублировать последовательность, и они работают немного быстрее.

Типичным алгоритмом RNG общего назначения является Mersenne Twister. Существует множество общедоступных реализаций различных алгоритмов. см. здесь один .

Если машинному переводу требуется слишком много памяти, более подходящим запасным вариантом является линейный конгруэнтный генератор. (МТ не был изобретен до 1997 года.) У этого генератора есть определенные проблемы, но он почти не требует памяти, почти не требует кода и очень быстр. Реализации есть везде, и они подробно описаны в книге Кнута Получисленные алгоритмы.

Для заполнения любого RNG вам понадобится источник энтропии, см. http://en.wikipedia.org/wiki/Entropy_(computing) (Примечание: SO путается с () в этой ссылке.) Обычно это происходит из-за событий синхронизации, которые может наблюдать ЦП, таких как нажатия клавиш (я предполагаю, что у вас не сработает) прерывания и приход пакетов. Часы реального времени часто являются приемлемым источником, если они поддерживают свое собственное состояние, поскольку перезагрузки редко синхронизируются в какой-либо последовательности.

person DigitalRoss    schedule 13.10.2009
comment
Эти RNG нуждаются в семени, чтобы работать. Каждый раз, когда микроконтроллер сбрасывается, я получаю один и тот же набор случайных чисел. - person Donotalo; 13.10.2009
comment
Ага, хороший вопрос. (Мы постоянно получаем основные вопросы о ГСЧ здесь, на SO, поэтому простите нас за то, что мы рефлекторно выдавали основной ответ. :-) В любом случае, я обновил свой ответ. Я сделаю еще одно обновление через минуту ... - person DigitalRoss; 13.10.2009
comment
Mersenne Twister использует пространство состояний, слишком большое для микроконтроллеров. - person starblue; 13.10.2009
comment
Большинство микроконтроллеров имеют АЦП, которые можно использовать в качестве источников энтропии. Оставьте только наименее значимые шумовые биты. - person endolith; 07.03.2012
comment
Почти любой приличный потоковый шифр также можно использовать в качестве ГСЧ, например, Salsa20 (или любой из другие шифры eSTREAM) (заполнение остается проблемой...) (требования к памяти, вероятно, нецелесообразны для большинство 8-битных устройств) - person Gert van den Berg; 18.04.2018

вы можете сохранить начальное значение в EEPROM, а при загрузке устройства вы можете увеличить начальное значение и сохранить его снова. Итак, при каждой перезагрузке у вас будет другое случайное число.

person Igor    schedule 03.12.2012

Если у вас есть доступ к АЦП, вы можете прочитать из него младший значащий бит и использовать его в качестве начального числа для генератора псевдослучайных чисел, как уже писали другие. Очевидно, вам нужно будет прочитать более одного бита из АЦП, поэтому необходимо несколько чтений, что может занять некоторое время. Но вам нужно сделать это только один раз, например, при запуске, а затем использовать более быстрый PRNG для генерации новых случайных чисел.

Многие встроенные устройства имеют встроенный АЦП, например семейство ATMega от Atmel.

person Marius    schedule 13.10.2009
comment
К сожалению, АЦП в ATMegas слишком стабилен. Даже LSB не меняется при многих чтениях. skemman.is/stream/get/1946/10689/25845/ 1/ardrand.pdf Мы изучили различные методы извлечения истинной случайности из микроконтроллера и пришли к выводу, что его не следует использовать для создания случайности из его аналоговых выводов. - person endolith; 24.04.2012

Если на оборудовании есть кнопка для пользователя, простой трюк — подсчитать, как долго кнопка нажата. При достаточно быстром коротком счетчике вы получите «случайное» число.

person Purple Tentacle    schedule 13.10.2009
comment
Знаете ли вы какие-либо оценки числа битов энтропии при скорости счетчика «x» Гц? - person Craig McQueen; 01.11.2009
comment
Извините но нет. Я думаю, что кто-то умный мог бы понять это. - person Purple Tentacle; 06.11.2009
comment
Это хорошее решение, но в моем случае мне нужно случайное число задолго до взаимодействия с пользователем (на самом деле, как только микро получает питание). Хотя спасибо за идею. - person Donotalo; 07.01.2010

Генераторы псевдослучайных чисел, которые являются самыми быстрыми и наименее требовательными к ресурсам. набор инструкций (только сдвиг и исключающее ИЛИ, без умножения или деления) представляет собой меньшие варианты идеи скручивания Мерсенна (называемого сдвиговым регистром с обобщенной линейной обратной связью). Сам твистер Мерсенна требует слишком много памяти для микроконтроллеров.

Проблема с этими генераторами заключается в том, что они могут генерировать длинные последовательности, близкие к нулю, если вам не повезет. Однако при разумном размере пространства состояний и инициализации из другого PNRG это маловероятно.

Они также небезопасны для криптографии или азартных игр, разумный противник может предсказать будущие состояния после наблюдения за выходом. Это потому, что они линейны.

Однажды я разработал такой генератор для небольшого нестандартного процессора с пространством состояний около 50 24-битных слов. Я тестировал варианты с набором тестов Diehard, пока не нашел хороший. Приложение генерировало случайные варианты для теста оборудования.

person starblue    schedule 13.10.2009

Чтение таймера и xoring/nanding/и т.д. с серией битов даст пользователю полуслучайное значение, так как время между событиями, вероятно, будет достаточно разнесено, чтобы пользователь не смог определить корреляцию с таймер.

person onaclov2000    schedule 06.01.2010

Если вы можете оставить булавку плавающей, это поможет генерировать случайные числа с помощью регистра сдвига с линейной обратной связью. Я не уверен, что это правильный путь, но, пожалуйста, взгляните на мой код:

// 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: я обнаружил, что мой ответ может быть плохим. Подробнее о том, почему не следует использовать плавающий цифровой PIN-код: https://electronics.stackexchange.com/questions/50476/random-number-generators-using-a-gpio-pin

person Hieu    schedule 16.11.2013