TG-RND7: Принцип генерации случайных чисел.
Принцип работы прибора основан на подсчете длительности нажатия на клавишу с очень высокой точностью.
В зависимости от режима ГСЧ оперирует с первичными алфавитами разной длины.
Все режимы подобны друг другу и построены по одинаковой схеме.
Для примера будет подробно рассмотрен режим генерации случайных чисел 1 из 10 (0-9).
---
В промежутке между нажатиями на кнопку "А" выполнчются различные служебные подпрограммы: динамическая индикация (вывод на индикатор соответствующего символа), проверка нажатия на кнопки и т.д.
При нажатии на кнопку генерации случайного числа "А" программа запускает соответствующий блок генерации числа.
Тактовая частота работы микроконтроллера составляет 20 000 000 Гц (20МГц), что указано на задающем частоту кварцевом генераторе.
То есть, длительность такта составляет 0,00000005 секунды, или 5*10^-8 сек.
Тактовая частота, деленная на четыре, дает длительность одного так называемого "машинного такта", то есть времени, в течение которого выполняется одна типовая команда ассемблера.
Такие команды, как "переход на метку", "пропустить если" и т.п., выполняются за два машинных такта, что будет особо отмечено ниже.
Таким образом, длительность 1 машинного такта (времени выполнения команды) составляет 0,0000002 секунды, или 2*10^-7 сек.
Ассемблерный код (MPASM) блока генерации 1 из 10.
Этот блок программа выполняет в том случае, если нажата кнопка "А" и выбра режим генерации 1 из 10 (0-9).
Переменная rand при этом уже равна нулю.
----------
; старт перебора
mDec_go
incf rand, f
movlw d'10'
subwf rand, w
btfsc STATUS, Z
clrf rand
btfss PORTB, 0
goto mDec_go
; конец перебора
----------
Для знающих ассемблер MPASM уже можно ничего не комментировать, для остальных - постараемся разобрать это настолько просто, насколько возможно.
Прим: заменим термин "рабочий регистр" на более прижившийся в русской литературе термин "аккумулятор".
Прим2: "аккумулятор" - это ячейка памяти для хранения данных, которую использует ядро процессора для большинства операций.
(для программистов: то есть это некая "основная переменная" с быстрым доступом, с которой работает командное ядро).
Переведем ассемблерный код на русский:
----------
; старт перебора (комментарий, не является командой, игнорируется микроконтроллером).
Метка строки (не является командой, указывает на номер строки начала цикла в памяти микроконтроллера)
- Увеличить переменную rand на 1
- Поместить в аккумулятор десятичное значение "10"
- Вычесть из аккумулятора значение переменной rand
- Если результат выполнения предыдущей команды не равен нулю (то есть значение переменной rand НЕ равно 10), то пропустить следующую команду (два такта: сама команда, и переход на следующую команду или пропускание ее)
- Обнулить переменную rand (пропускается если rand не равно 10)
- Если на выводе контроллера логическая единца (кнопка не нажата), то пропустить следующую команду (два такта)
- Перейти на метку, на начало цикла (пропускается, если кнопка "А" отпущена) (два такта)
; конец перебора (комментарий, не является командой, игнорируется микроконтроллером).
-------
Таким образом, основной цикл состоит из 6 команд длительностью в 1 такт, и команды перехода на метку начала цикла длительностью 2 такта.
То есть, длительность основного цикла составляет 8 тактов, или 8*2*10^-7=0,0000016 секунд, или 1,6*10^-6 сек, или 1,6 микросекунд.
В этом цикле программа перебирает значения от 0 до 9 до тех пор, пока не будет обнаружено, что кнопка отпущена.
На этом генерация случайного числа заканчивается, далее следуют служебные подпрограммы.
То есть, каждое значение "существует" всего 1,6 мкС, и чтобы "специально" сгенерировать не случайное число, мы должны уложиться в промежуток времени 1,6/1000000 секунды.
Для приведенного случая (1 из 10) вся длительность полного перебора составляет 16 мкс секунд, или 1,6*10^-5 сек., или 1,6/100000 сек., за это время программа перебирает значения от 0 до 9 и начинает перебор снова.
По различным оценкам время, с которым обычный человек может нажимать кнопку "в такт", составляет порядка 1/10 сек, у специально тренированных людей отдельных профессий - не более 1/100 секунды.
То есть за 1/10 секунды, пока человек пытается "попасть в такт", программа переберет полный цикл 62500 раз и в момент отпускания кнопки остановится на каком-то случайном значении.
Так же, следует учесть такое явление, как "дребезг контактов": электрически нажатие кнопки не моментально замыкает контакты, а при отпускании - не сразу размыкает.
При столь высокой частоте работы замыкание и размыкание механических контактов представляет собой сложный переходной процесс, зависящий от таких причин, как микровыпуклости на пластинах контактов, их упругость, степень усталостной деформации, влажность воздуха и т.д.
Все это увеличивает "случайность" генерации чисел.
Несколько других факторов так же увеличивают "случайность", но рассмотрение их выходит за рамки данного материала и в целом не принципиально.
Фактически сгенерированное число/символ - это результат ОЧЕНЬ многих процессов.
Часть из которых строго детерминизирована (но далеко за пределами человеческих способностей по восприятию или управлению).
А часть - совершенно хаотична.