Генератор псевдовипадкових чисел
Генератор псевдовипадкових чисел ('ГПВЧ, англ. pseudorandom number generator, PRNG) — це алгоритм або пристрій, який за допомогою детермінованої процедури та початкового значення (зерна, англ. seed) породжує послідовність чисел, що за своїми статистичними властивостями наближається до послідовності істинно випадкових чисел.
Істинно випадкові числа отримують з фізичних процесів, що вважаються непередбачуваними (тепловий шум, радіоактивний розпад, квантові ефекти тощо), і такі генератори називають генераторами істинно випадкових чисел (англ. true random number generator, TRNG). Псевдовипадкові генератори натомість повністю детерміновані: однакове початкове зерно відтворює ту саму послідовність, але при належному виборі алгоритму ця послідовність проходить складні статистичні тести та є достатньо «випадковою» для більшості прикладних задач.
Вперше запропонував їх використовувати Джон фон Нейман у 1946 р. Його метод полягав в наступному: n-розрядне число підносилось до квадрата і з нього вибиралися середні n цифр. Метод був дуже недосконалий, послідовності майже завжди вироджувалися в нуль або зациклювалися з коротким періодом. Пізніше було запропоновано багато різних алгоритмів отримання псевдовипадкових чисел.
Псевдовипадкові числа широко застосовуються в методі Монте-Карло та інших чисельних методах моделювання, у статистиці, комп’ютерній графіці та іграх, у криптографічних протоколах (для генерації ключів, ініціалізаційних векторів, nonce тощо), при тестуванні програмного забезпечення та в інших галузях, де потрібні відтворювані, але статистично якісні послідовності випадкових значень.[1] [2] [3]
Мультиплікативний конгруентний метод (англ. multiplicative congruential generator, MCG, або генератор Лемера) є окремим випадком лінійного конгруентного генератора, у якому доданок дорівнює нулю. Рекурентна формула має вигляд
- ,
де — модуль, — множник, а — початкове значення (зерно). Для фіксованих і така схема визначає дискретну динамічну систему з періодичною траєкторією; при вдалому виборі параметрів період послідовності наближається до .[4]
В основі програмних генераторів як правило лежать рекурентні формули. Як правило, вони генерують цілі числа рівномірно розподілені на відрізку від 0, до деякого максимального m. Щоб отримати числа з рухомою комою, рівномірно розподілені на [0,1), кожен отриманий результат ділять на m.
Класичний приклад — так званий minimal standard генератор Парка — Міллера з параметрами і , який довгий час використовувався в чисельних симуляціях.[5]
Як просту ілюстрацію можна розглянути , , : послідовність значень дорівнює і має період 6. Переваги методу — простота реалізації та висока швидкодія; недоліки — відносно невеликий період і помітні кореляції між послідовними значеннями для невдалих параметрів, що обмежує застосування в задачах, чутливих до якості випадковості, зокрема в криптографії.[1] [6]
Ця формула має багато часткових випадків:
Цей розділ потребує доповнення. (квітень 2010) |
Змішаний конгруентний метод (англ. mixed congruential generator) відповідає загальному випадку лінійного конгруентного генератора з ненульовим доданком. Рекурентна формула має вигляд
- ,
де — модуль, — множник, — доданок (інкремент), а — зерно.[5] При певних умовах на параметри (теорема Галла — Добелла) такий генератор має повний період довжини для будь-якого початкового значення.
Змішані конгруентні генератори історично були одними з найпоширеніших завдяки простоті та швидкості, і реалізовувалися в стандартних бібліотеках багатьох мов програмування (зокрема як функції типу rand()).[5] Однак якість згенерованих послідовностей сильно залежить від вибору параметрів: невдалі набори і призводять до короткого періоду та сильної кореляції між багатовимірними точками, що може спотворювати результати моделювання. Через це в сучасних застосуваннях для серйозних наукових симуляцій рекомендують використовувати більш сучасні генератори або ретельно підібрані параметри LCG.[2]
Цей розділ потребує доповнення. (квітень 2010) |
Квадратичний конгруентний метод' (англ. quadratic congruential generator, QCG) узагальнює лінійний конгруентний підхід шляхом додавання квадратного члена. Рекурентне співвідношення можна записати як
- ,
де , , — цілі коефіцієнти, — модуль, а — початкове значення.[7] Уведення квадратичного члена ускладнює аналіз і може покращувати деякі статистичні властивості порівняно з простими LCG, проте повністю не усуває лінійних кореляцій у багатовимірному просторі.
Квадратичні конгруентні генератори детально досліджувалися в контексті теорії рівномірного розподілу та криптоаналізу, але на практиці використовуються рідше, ніж мультиплікативні й змішані конгруентні генератори або сучасніші схеми на основі регістрів зсуву. Їхні переваги — відносна простота реалізації та можливість отримати довші періоди для деяких модулів; до недоліків належать складніший аналіз якості та наявність ефективних атак у разі використання в криптографічних протоколах.[7] [6]
Запропонований Д. Х. Лемером. Основна обчислювальна формула:
Алгоритм зациклюється з періодом, що не перевищує деякого m. Коефіцієнти а, m і x(0) можуть приймати довільні цілі значення, за винятком 0. Параметр с може бути також і 0, але в цьому випадку скорочується період. Число ітерацій m звичайно вибирається рівним максимальному значенню типу, що робить непотрібною операцію ділення, яка автоматично виконається при переповненні. Число а можна взяти рівним, наприклад, 1664525, с — рівним 1013904223. Такий метод часто реалізують в сучасних системах програмування, хоча він майже непридатний у галузі статистики чи криптографії, де вимоги до «випадковості» значно вищі.
Запропонований Джорджем Марсалією (Marsaglia), професором університету Флориди. Обчислювальна формула:
Цей алгоритм є узагальненням попереднього і позбавлений його головного недоліку — короткого періоду. Його період — [8].
Випадкове число належатиме проміжку [0, 1). Початкові значення можна задавати довільні. Алгоритм може бути застосований в прикладних науках, але він має нижчу швидкість.
Лінійний конгруентний генератор задається рекурентним співвідношенням . Це один із найстаріших і найпростіших класів ГПВЧ: реалізація потребує лише однієї операції множення, додавання та обчислення остачі.[5] Переваги LCG — висока швидкодія та малий обсяг стану; недоліки — сильні кореляції у багатовимірному просторі й чутливість якості до вибору параметрів. Такі генератори часто застосовувалися в ранніх симуляційних пакетах і стандартних бібліотеках мов програмування, але нині вважаються застарілими для вимогливих статистичних задач.
Під назвою Mother-of-All описують сімейство генераторів Джорджа Марсальї, основаних на методі multiply-with-carry (MWC). Стан генератора складається з кількох попередніх значень і «переносу», а нове значення обчислюється як лінійна комбінація попередніх значень, помножена на константи, з урахуванням переносу.[9] Такі генератори забезпечують дуже довгі періоди (до і більше) та високу швидкодію, завдяки чому їх застосовують у комп’ютерних іграх і деяких симуляційних системах. Водночас вони не призначені для криптографічного використання й потребують ретельного добору параметрів, щоб успішно проходити сучасні статистичні тести.[2]
Вихор Мерсенна запропонований у 1997 Макуто Матсумото і Такеджі Нушиміро. Основна ідея полягає в тому, що до початкової ітерації, яка ініціює процедуру, застосовується серія бітових операцій. Після їх виконання отримують нову послідовність, перший член якої вважається псевдовипадковим числом. Цей алгоритм має величезний період: ітерації (це більше ніж ).
До інших популярних класів ГПВЧ належать генератори на основі регістрів зсуву з лінійним зворотним зв’язком (LFSR) та їхні комбіновані схеми, лагові генератори Фібоначчі, багаторекурсивні конгруентні генератори, а також криптографічно стійкі генератори, що будуються на блокових шифрах, потокових шифрах або криптографічних геш-функціях.[6] У виборі конкретного алгоритму враховують компроміс між швидкодією, обсягом стану, складністю реалізації та вимогами до статистичної якості послідовності.
Алгоритм дуже швидкий через відсутність множень, але не має достатньої випадковості. Тому галузь застосування алгоритму дещо обмежена.
Одні з найновіших генераторів від Джорджа Марсалії. Знову розглядається деяка початкова послідовність, до якої застосовуються операції xor та побітові зсуви. Ці операції полягають в наступному:
Замість shl можна використовувати також shr, та еквівалентне множення.
Алгоритм має період та проходить тести Diehard.
Підсумкове випадкове число може бути одержано за допомогою підсумовування окремих членів послідовності, або застосування до них операції xor. В наш час[коли?] це один з найбільш вживаних алгоритмів; послідовність, що генерується, достатньо випадкова, періоди — від (залежно від реалізації), відсутність операцій множення позитивно позначається на швидкості.
У методі Монте-Карло та пов’язаних із ним стохастичних алгоритмах генератори псевдовипадкових чисел використовують для моделювання випадкових подій, чисельного інтегрування, оптимізації та розв’язання диференціальних рівнянь.[3] Якість ГПВЧ безпосередньо впливає на упередженість і дисперсію оцінок: поганий генератор може давати систематично перекручені результати, особливо в довготривалих симуляціях високої точності.[10]
У криптографії випадкові та псевдовипадкові числа використовують для формування ключів шифрування, генерації ініціалізаційних векторів, nonce та одноразових параметрів протоколів аутентифікації.[11] Звичайні швидкі генератори (LCG, Mersenne Twister тощо) не забезпечують криптографічної стійкості, адже їхній внутрішній стан можна відновити за достатньо великою підпослідовністю вихідних значень. Тому для криптографії застосовують криптографічно стійкі генератори псевдовипадкових чисел (CSPRNG), які ґрунтуються на блокових і потокових шифрах, криптографічних геш-функціях або спеціалізованих конструкціях і часто комбінуються з фізичними генераторами істинно випадкових чисел.[11]
У комп’ютерних іграх ПВЧ використовуються для моделювання випадкових подій (кидання «віртуальних кубиків», випадкова поведінка супротивників, дроп предметів тощо) та процедурної генерації рівнів, карт, ландшафтів і завдань.[12] Використання детермінованого генератора із зафіксованим зерном дозволяє відтворювати один і той самий ігровий світ (наприклад, за «сидом» світу), що зручно як для розробників, так і для гравців. Вимоги до статистичної якості тут зазвичай м’якші, ніж у наукових симуляціях, але вища швидкодія має критичне значення.
У більшості сучасних мов програмування стандартні бібліотеки містять як «звичайні» генератори загального призначення, так і окремі засоби для криптографічно стійкої випадковості.
У мові C стандартна функція rand() зазвичай реалізується як лінійний конгруентний генератор із 31-бітним станом, що вважається недостатнім для вимогливих задач моделювання. У C++ починаючи з C++11 стандартна бібліотека <random> містить низку генераторів, серед яких широко використовується std::mt19937 — реалізація Mersenne Twister MT19937 із періодом .[13]
Для криптографічних задач у C/C++ зазвичай звертаються до спеціалізованих бібліотек (OpenSSL, libsodium тощо), які надають CSPRNG поверх системних джерел випадковості.
У Java клас java.util.Random реалізує 48-бітний лінійний конгруентний генератор і призначений для загальних задач моделювання та ігор, але не для криптографії.[14] Для безпечної генерації випадкових чисел використовується клас java.security.SecureRandom, який звертається до криптографічно стійких алгоритмів і джерел ентропії операційної системи.[11]
У Python модуль random за замовчуванням використовує генератор Mersenne Twister MT19937,[15] а модуль secrets поверх os.urandom() надає інтерфейс до криптографічно стійкого джерела випадковості, рекомендованого для створення паролів, токенів та інших секретів.[16] Такий поділ відображає загальну практику: швидкі генератори використовують для чисельних експериментів, тоді як CSPRNG застосовують у безпекових сценаріях.
- 1 2 Knuth, Donald E. The Art of Computer Programming. Vol. 2: Seminumerical Algorithms. Addison–Wesley.
- 1 2 3 L'Ecuyer, Pierre. «Uniform random number generation». Annals of Operations Research, 1994.
- 1 2 Gentle, James E. Random Number Generation and Monte Carlo Methods. Springer.
- ↑ Park, Stephen K.; Miller, Keith W. «Random number generators: Good ones are hard to find». Communications of the ACM, 1988.
- 1 2 3 4 L'Ecuyer, Pierre. «Random numbers for simulation». Communications of the ACM, 1990.
- 1 2 3 L'Ecuyer, Pierre. «Random Number Generation». У кн.: Handbook of Computational Statistics. Springer.
- 1 2 Knuth, Donald E. The Art of Computer Programming. Vol. 2: Seminumerical Algorithms. Розділ про квадратичні конгруентні генератори.
- ↑ Архівована копія. Архів оригіналу за 21 вересня 2011. Процитовано 17 грудня 2010.
{{cite web}}: Обслуговування CS1: Сторінки з текстом «archived copy» як значення параметру title (посилання) - ↑ Marsaglia, George. «Mother of all random number generators». Технічна записка / матеріали автора, приблизно 1990-ті роки.
- ↑ Gentle, James E. Random Number Generation and Monte Carlo Methods. Розділи про застосування генераторів у методі Монте-Карло.
- 1 2 3 Menezes, Alfred J.; van Oorschot, Paul C.; Vanstone, Scott A. Handbook of Applied Cryptography. CRC Press. Розділ про генератори псевдовипадкових бітів.
- ↑ O'Neill, Melissa E. «PCG: A family of simple fast space-efficient statistically good algorithms for random number generation». Технічний звіт, 2014.
- ↑ C++ standard library reference. Опис заголовка
<random>і генератораstd::mt19937. - ↑ Java Platform, Standard Edition API Specification. Документація класу
java.util.Random. - ↑ Python 3 Standard Library. Розділ «random — Generate pseudo-random numbers».
- ↑ Python 3 Standard Library. Розділ «secrets — Generate secure random numbers for managing secrets».
- Knuth, Donald E. The Art of Computer Programming. Volume 2: Seminumerical Algorithms. — 3rd. — Reading, MA : Addison–Wesley, 1997. — ISBN 0-201-89684-2.
- Park Stephen K. Random Number Generators: Good Ones Are Hard to Find // Communications of the ACM. — 1988. — Т. 31, № 10. — С. 1192–1201. — DOI:10.1145/63039.63042.
- L'Ecuyer Pierre. Uniform Random Number Generation // Annals of Operations Research. — 1994. — Т. 53. — С. 77–120. — DOI:10.1007/BF02136827.
- L'Ecuyer Pierre. Uniform Random Number Generators: A Review // Proceedings of the 29th Winter Simulation Conference. — 1997. — С. 93–105.
- Matsumoto Makoto. Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator // ACM Transactions on Modeling and Computer Simulation. — 1998. — Т. 8, № 1. — С. 3–30. — DOI:10.1145/272991.272995.
- L'Ecuyer Pierre. TestU01: A C Library for Empirical Testing of Random Number Generators // ACM Transactions on Mathematical Software. — 2007. — Т. 33, № 4. — DOI:10.1145/1268776.1268777.
- Marsaglia George. Diehard: a battery of tests of randomness. — 1995.
- L'Ecuyer Pierre. Random Number Generation. — Springer, 2012.
- Нємкова. Порівняльне дослідження тестів для оцінки статистичних властивостей генераторів випадкових та псевдовипадкових послідовностей // Питання кібербезпеки. — 2024.
- Gentle, James E. Random Number Generation and Monte Carlo Methods. — 2nd. — New York : Springer, 2003.