Доброго времени суток! Решил рассказать о простом и интересном способе получения честных случайных чисел на микроконтроллерах, не имеющих на борту аппаратного генератора случайных чисел. Достаточно, чтобы у микроконтроллера был АЦП и один свободный вход. Подробности под катом.
Идея не нова и много кому приходила в голову. Я её реализовал в одном из своих старых проектов на STM8S003F3, так что примеры кода будут к этому чипу, хотя перенести код на любую другую архитектуру не составит труда.
Суть заключается в том, что при измерении напряжения при помощи АЦП младшие биты результата наиболее подвержены шумам. Мы используем этот факт себе на пользу — будем делать несколько замеров, и записывать младший бит результата (как самый «шумный»). Таким образом сделав 8 измерений можно получить совсем случайный байт.
Ухудшим результаты измерения насколько это возможно. Установим наименьшее время выборки, а вывод микроконтроллера, на котором расположен вход АЦП, повесим «в воздухе», никуда не подтягивая и ни к чему не подключая. Чем больше шума — тем лучше.
Инициализация АЦП:
CLK_PCKENR2 |= 0x08; //Подаём тактирование на АЦП
ADC_CR1 = MASK_ADC_CR1_ADON; //Включение
ADC_CR2 = MASK_ADC_CR2_ALIGN;
ADC_CR3 = 0;
ADC_CSR = 4; //Выбор канала
Функция получения случайного байта:
unsigned char GetRandom(void) {
unsigned char i, result;
result = 0;
for (i = 0; i < 8; i++) {
ADC_CR1 = MASK_ADC_CR1_ADON; //Старт преобразования
while (ADC_CSR == 4); //Ждём установки флага окончания преобразования
result = (result << 1) + (result & 0x01);
ADC_CSR = 4; //Сбрасываем флаг окончания преобразования
}
return result;
}
Вот такая небольшая хитрость. Код восстанавливал по памяти, так что могут быть ошибки — о них прошу написать в ЛС.
Буду очень рад мнению опытных людей о таком способе получения случайных чисел.
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий