Просмотр полной версии : Случайные числа [ Vc++ ]
Интересует данная тема (Случайные числа в MVС++ и их генератор). В делфи имеется функция Random в паре с Randomize. Как быть с получением случайных чисел в VС++ ? Может есть свои методы или модули ? Подскажите плз, в каком направлении копать или у кого подобный вопрос уже решался и имеются наработки...
// Ну и для извращенцев, интересны технологии создания генератора
для псевдослучайных используют функцию rand() из RTL.
xqwerx, вот тебе исходник по теме:
#include <windows.h>
#include <stdio.h>
unsigned long rs_randseed;
void _srand()
{
rs_randseed = GetTickCount();
}
unsigned long _rand()
{
rs_randseed++;
return (rs_randseed*0xF02CE551) + 0x7FF2742B;
}
int main()
{
int a;
_srand();
a=_rand();
char *pa;
printf("This: ",itoa(a,pa,10));
return 0;
}
Числа, которые генерируются обоими методами - не случайные. Для генерации числовой последовательности, близкой к случайной, используют специальные сложные железки + апи к ним.
Ni0x С часиками интересно получилось! Главное фантазия :) А я то загонялся со стековым генератором ....
iv. , я не говорю что получаются случайные числа, я вроде написал для псевдослучайных
ТС: srand/rand читай описание к CRT.
Реализовать генератор можно проще... Rdtsc и все дела.
смотря что понимать под случайностью. пусть надо сгенерировать "случайное" двухбайтное число (если меньше то отрубаем результат mod по границе, если например четырехбайтное то аналогично) не используя "железок". под случайным числом будем понимать результат 16-ти бит, такой что кол-во битов установленных в единицу в среднем будет никак не меньше битов установленных в ноль и более того, среднее количество "попаданий" в старший не должно быть меньше или больше чем в младший. полное равноправия битов в среднем, однако расположение их в текущий момент времени должно быть абсолютно случайно:) по этой причине, пример от Ni0x ну вообще не годится, хотя бы потому, что умножение на число ну никакой случайности не добавляет, а сложение и тем более на случайность выпадения битов. могу предложить только аналогичный вариант, но с циклическим сдвигом результата на половину слова (в данном случае на 8 бит) и двоичного сложения с первоначальным... потому что xor абсолютно демократичен как к 1 так и к 0, а сдвиг добавит равноправия между старшими и младшими битами.
если кому интересно, в библиотеке boost для c++ есть уже готовые решения
http://boost.org/libs/random/index.html
Смотря, для каких целей. Если нужно статистическая случайность, то открываешь второй том Дональда Кнута "Искусство программирования" и узнаешь все что необходимо.
Aag Открывать и смотреть, а так же по google лазать - это все понятно!
Я личные мнения каждого по теме хотел послушать...
интересны технологии создания генератора
я думал тебе интересны технологии, а тебе блюдечко нужно с голубой каемочкой.
А мое мнение таково, что если нужна стандартная вещь, то просто открой справочник (в данном случае Кнута "Искусство программирования" или другой источник).
Я личные мнения каждого по теме хотел послушать...
Как сказал один человек, генерация случайных чисел - слишком важное дело, чтобы оставлять её на волю случая.
Aag Я могу повториться... :) Это часть процесса познания - гляжу по справочникам, книгам, на wasm много всяких примерчиков, вот здесь спрашиваю....
А на блюдечке с голубой каемочкой можешь пока чаек пить ;)
P.S. За Дональда Кнута спс... обязательно гляну...
А асм вставку разве нельзя зделать!
Lamia А ты знаешь как лучше сделать генератор псевдослучайных чисел на assemblere? Хотя бы примерно случайно и на хорошей реализации на асме... Я бы поглядел с удовольствием!
А асм вставку разве нельзя зделать!
напиши на асме генератор случайных чисел, именно случайных.
Генераторы случайных и псевдослучайных я сама реализовывать не пробывала,но в в сети достаточьно исходников различьных вирусов,где они применяются!И не уж то ты считаеш что генератор на Си будел лучше по своей случайности чем на асме!?
Lamia Поэтому и спрашиваю, что да как лучше будет! Какую технологию использовать для реализации на асм? Я слышал и читал только про стековый генератор, но уж слишком загонно!
ReanimatoR
12.07.2007, 09:01
я всегда пишу генератор от функции timer();. цыфр добуя. Меняются быстро=) вот и генератор вам). на vb довел его до совершенства, как мне кажется.
The_HuliGun
12.07.2007, 10:34
Самый простой математический метод генерации псевдослучайных чисел есть линейный конгруэнтный метод. Следующее число последовательности расчетывается исходя из предыдущего по формуле
x2 = (a*x1 + c) mod m
где a,c,m параметры последовательности, а mod - остача от деления. Есть теорема, выполнение условий которой гарантирует появление последовательности с полным периодом, т. е. псевдослучайные числа будут набирать всех значений от 0 до m:
1. c и m взаимно просты.
2. a - 1 кратно p для всех простых p — делителей m;
3. a - 1 кратно 4, если m кратно 4.
Если надо получить псевдослучайное число в интервале от 0 до 1, тогда результат делят на m.
Lamia Поэтому и спрашиваю, что да как лучше будет! Какую технологию использовать для реализации на асм? Я слышал и читал только про стековый генератор, но уж слишком загонно!
У тя ж в джойнере полиформизм вроде присутствует!
Значит там и генератор псевдослучайных чисел есть!
Чем он тя не устраивает,не так случайно кости выпадают?
Абсолютной случайности всеравно не получится!Если
самому написать близкий к идеалу не получается,то приходится выбирать из чужих!
Выбирай: http://vx.org.ua/29a/main.html
Может что и нароеш..там и си и асм
:)
;by Slon
brandom32:
push edx ecx
xor edx,edx
imul eax,eax,100
push eax
call random32
pop ecx
div ecx
xchg eax,edx
xor edx,edx
mov ecx,100
div ecx
pop ecx edx
ret
random32:
push edx ecx
db 0fh,031h
rcl eax,2
add eax,12345678h
random_seed = dword $-4
adc eax,esp
xor eax,ecx
xor [random_seed],eax
add eax,[esp-8]
rcl eax,1
pop ecx edx
ret
Lamia, я не говорю что на asm генератор будет хуже, я своим высказыванием имел ввиду, что написать генератор случайных чисел очень сложно на любом языке, даже более того, почти невозможно.
А я и не спорю!Именно случайных....
Lamia В джойне случайные числа делаются стандартными методами! А вот иметь свой генератор приблеженный хотя бы к Random() для проектов на асме - это уже плюсег (тебе)!!!!
P.S. Всем откликнувшимся спасибо, собрал много инфы и интересных идей!
Генератор не мой!А отсюда http://www.wasm.ru/article.php?article=virii_weapon
На Wasm так же есть тестировщик ГПСЧ
У меня многопоточность......rand() используется раза три в функции SomeFunction
----каждый поток выглядит так
OneThread()
{
while(i--)
SomeFunction()
}
встречаются повторяющееся последовательности...че делать)
использовал srand(time(0)) соответсвенно не пашет ...
inv а ты инициализировал генератор, вот так:
time_t MyTime;
srand((unsigned)time_t(&MyTime)*1000000);
???
К черту rand вместе с crt. Напиши функцию, которая будет генерировать тебе псевдослучайное число с помощью GetTickCount(). Я выкладывал вроде пример в топике "с++ задай вопрос - получи ответ", глянь последние страницы.
Ni0x
у меня потоки......а там обращение ко времени получается к одному и тому же
я делал так
EnterCriticalSection(&cs);
srnd();//моя srand
....обращение к песевдослу числу
szRandUrl(login,passwd,url);
не помогло
Твое пробовал че-то вообще не покатило)))))))))
У меня есть несколько потоков
в каждом потоке просто выводятся рандомные строчки
потоки работают одновременно
Мне нужно чтобы ВСЕ строчки были разные....пока что не получилось.
едиснтвенное пока что пришло в голову это присабачивать к srand номер потока.
inv, надеюсь я правильно тебя понял.
#include <windows.h>
unsigned long rs_randseed;
void _srand()
{
rs_randseed = GetTickCount();
}
unsigned long _rand()
{
rs_randseed++;
return (rs_randseed*0xF02CE551) + 0x7FF2742B;
}
unsigned int __stdcall Base(PVOID pArg)
{
int a = 0;
char pa[12];
_srand();
a=_rand() % 1000;
itoa(a, pa, 10);
MessageBox(0, pa, "Hi", 0);
return 0;
}
int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hHan[9];
for(int i; i<9; i++)
{
hHan[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Base, 0, 0, 0);
}
WaitForMultipleObjects(9, hHan, TRUE, INFINITE);
for(int j; j<9; j++)
{
CloseHandle(hHan[j]);
}
return 0;
}
#include <windows.h>
#include <stdio.h>
unsigned long rs_randseed;
void _srand()
{
rs_randseed = GetTickCount();
}
unsigned long _rand()
{
rs_randseed++;
return (rs_randseed*0xF02CE551) + 0x7FF2742B;
}
unsigned int __stdcall Base(PVOID pArg)
{
int a = 0;
char pa[12];
_srand();
a=_rand() % 1000;
itoa(a, pa, 10);
printf("<%s>\n",pa);
return 0;
}
int main()
{
HANDLE hHan[9];
for(int i=0; i<9; i++)
{
hHan[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Base, 0, 0, 0);
}
WaitForMultipleObjects(9, hHan, TRUE, INFINITE);
for(int j=0; j<9; j++)
{
CloseHandle(hHan[j]);
}
return 0;
}
одинаковые числа=\с мессаджами не одинаковые само собой так как там время тратится на окошки
смысл не в этом...смысл во времени
может использовать другую псевдослучайную посл...
*********
проблему решил,использовал псевдо случпоследовательность(не зависит от времени) ,иницилизировал временем.
rs_randseed++;
Алгоритм такой должен быть - rand_init() просто сохраняет в переменной значение GetTickCount(), а далее каждый раз, вызваная rand()-ф-ия искривляет его, например, умножает на 0xf25a0cb2 и т.п. и возвращает. Тогда значения будут разными. А у тебя зачем-то на единицу увеличивается, а потом от нее считается. Можно было бы додуматься. И ещё, не юзайте там лишнего всяких умножений, а то потом rand()-ф-ии будут занимать времени больше, чем все потоки вместе взятые
О чем тут ещё можно говорить?
Много всяких случайностей еще можно придумать кроме времени для инициализации: состояние памяти в каком-нибудь месте, уровень входного звукового сигнала, загруженность процессора, количество занятой оперативной памяти и т.д. Можно это все как-то комбинировать и получить генератор больменее случайных чисел без всяких железяк. Только тогда надо будет не инкрементить rand_seed (или умножать его на что-то там и т.д.), а так же его постоянно откуда-то рандомно получать. Хотя функция тогда будет занимать много времени...
Great: Ммда ))) ZaCo, +1
Советую посмотреть PWGen 1.40 Sources (http://downloads.sourceforge.net/pwgen-win/PWGen-1.40-Src.zip?modtime=1086393600&big_mirror=0)...
Kez, алгоритм не мой, я просто разместил объяву. Согласен - нетемовый, исправим.
я же написал в первом посте этой теме - главное это ЧТО в СВОЕЙ программе ВЫ считаете случайным числом. не понимаю, зачем нужно формирование "случайной" последовательности наиболее близкой к жизненной, человеку, скорее всего, не занимающимся созданием ключей для шифрования? и то - взять тот же стеганос, он сам просит пользователя рандомно повозить мышкой по экрану или постучать по клавиатуре:)
для игр - существуют алгоритмические способы формирования таких последовательностей с равномерным распределением значений по множеству int чисел, все это описано у кнута.
--
куда интереснее было бы почитать про анализ алгоритмически-построенной последовательности на "случайность" и про возможное предположение о продолжении последовательности.
Псевдослучайное число это значит число, которое на самом деле не случайное и при знании алгоритма функции rand и начальных условий можно восстановить всю цепочку вызовов этой функции, а если знать как окргуляли эти числа, то случайными они уже никак не будут.
А случайные числа это те, у которых практически невозможно предсказать начальные условия (в худшем случае) или те, у которых вообще нет начальных условий (т.е. с учетом состояния рандомизирующих элементов генерируется всякое случайное число), разумеется в большинстве случаев это совершенно ненужно, я даже плохо представляю когда это может понадобиться.
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot