Генератор случайных чисел

Опубликовано в M4

Разбирал свою старую писанину - наткнулся на несложный генератор случайных чисел на препроцессоре M4. Позволяет генерировать целые псевдослучайные числа в заданном диапазоне на этапе сборки программы.

 

define('m4_ifval', 'ifelse('$1','','$3','$2')')
define('m4_default', 'm4_ifval('$1','$1','$2')')
dnl ========== m4_random(max=2796203) =================
define('m4$random$value',patsubst(substr(esyscmd(time /T),0,5),':'))
define('m4_random','define('m4$random$value',eval((indir('m4$random$value') * 125) % 2796203))eval((indir('m4$random$value')%m4_default('$1',2796203))+1)')

Попробуем:

Вызов Результат
m4_random() 266751
m4_random() 2585518
m4_random() 1626281
   
m4_random(50) 35
m4_random(50) 40
m4_random(50) 22
m4_random(50) 6
m4_random(50) 30
m4_random(50) 33
m4_random(50) 15
   
m4_random(5) 1
m4_random(5) 5
m4_random(5) 2
m4_random(5) 1
m4_random(5) 4

 Зачем понадобилось? Всякие вопросы секретности при генерации исходных текстов.

 

 


 

Другой вариант. Используются следующие идеи:

 

  • mkstemp (или maketemp) создает уникальный файл с именем из 6 алфавитно-цифровых символов. 
  • eval позволяет интерпретировать эти символы как число с основанием 36.
  • Чтобы не было переполнения 4-байтового long, с которым работает препроцессор m4, cтарший разряд полученного числа, равный Z(36), отбрасывается посредством patsubst.
  • Остаток от деления позволяет выбрать верхнюю границу для создаваемых чисел.

 

define(`m4_trim_left',`patsubst(`$1',m4_default(`$2',`^ *'),`')')
define(`m4_random',`pushdef(`_', maketemp())syscmd(`del /Q' _)eval(0r36:m4_trim_left(_,`^[zZ]')%m4_default(`$1',2147483647))popdef(`_')')

 

Добавить комментарий


Защитный код
Обновить

Библиотека