Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
#1

Генератор псевдо-случайных чисел, как хэш-функция

28.05.2017, 21:29. Просмотров 1667. Ответов 50
Метки rand (Все метки)

Анализируя генератор псевдослучайных чисел

Я пришел к выводу, что (Учитывая что RAND_MAX = 32767)

придумал сам, но может где то подобное писалось (просто я не искал)
C++
1
2
unsigned long NewT((unsigned long (time(NULL) << 10)) + (clock()&1023));
srand(NewT);
Лучше, почему?
Такое же число NewT может появиться только через ~ 48 дней
Оно способно давать псевдослучайное число каждую ~ миллисекунду
Такое же случайное число может получиться через ~32,768 секунд

чем обычное
C++
1
srand(time(NULL));
Такое же число time(NULL) не сгенерируется уже никогда (~135 лет)
способно давать псевдослучайное число - каждую секунду
Такое же случайное число может получиться через ~9 часов 6 минут

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
 
int i;
const int r(RAND_MAX + 1);
unsigned int m, M, k, R[r];
 
void main()
{
    do{
        srand(k);
        ++R[rand()];
 
        if(!(++k << 8))
        {
            i = 0;
            m = M = R[0];
            while(++i != r)
                if(R[i] < m) m = R[i];
                else
                    if(R[i] > M) M = R[i];
            cout << ((k-1) >> 24) << "> Count RAND(min, max) = [" 
                 << m << ", " << M << "]" << ((m == M)?("\n<"):("\r<"));
        }
    }while(k);
 
    cout << "\nPress ENTER to continue...";
    cin.get();
}
Итог очень интересный:
Кликните здесь для просмотра всего текста
<127> Count RAND(min, max) = [65536, 65536]
<255> Count RAND(min, max) = [131072, 131072]
Press ENTER to continue...

Получается что в некоторых точках функция равномерная (т.е. равномерно распределяется значения)
что есть хорошо)
в конечном результате, как видно получается R[i] = 131072 (каждое)

Если кто уже делал подобное изучение генерации псевдо-случайных чисел, скинуть где прочитать)
(читал, но что то подобных не находил)

Добавлено через 6 минут
Можно конечно использовать:
C++
1
unsigned long NewT((time(NULL)/1000) + (clock()%1000));
НО как мне кажется (деление на 1000)/(остаток от деления на 1000) - не дает
такое же равномерное распределения как и (сдвиг влево на 10)/(маска 0x03ff)

Хотя, для каждого конкретного случая, лучше подбирать свой способ

Добавлено через 9 минут
Например если встряхивается только один раз,
то логичнее писать:
C++
1
srand(time(NULL));
но если нужно встряхнуть в цикле, например раз 10-15, то лучше пользоваться:
Цитата Сообщение от eXPonent Посмотреть сообщение
unsigned long NewT((time(NULL)/1000) + (clock()%1000));
так выполнения одной итерации может занимать меньше одной секунды.

Добавлено через 1 час 11 минут
Теоретическое время выполнения
вот такой проги (9 дней) нужно как нить ускорить
хочу увидеть когда наблюдается равное распределение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
 
int i;
const int r(RAND_MAX + 1);
unsigned int m, M, k, R[r];
 
void main()
{
    do{
        srand(k);
        ++R[rand()];
 
        i = 0;
        m = M = R[0];
        while(++i != r)
            if(R[i] < m) m = R[i];
            else
                if(R[i] > M) M = R[i];
 
        if( (m == M) || (!(short)k))
            cout << k << "> Count RAND(min, max) = [" << m
            << ", " << M << "]" << ((m == M)?("\n<"):("\r<"));
    }while(++k);
 
    cout << "\rPress ENTER to continue...";
    cin.get();
}
Добавлено через 2 часа 40 минут
Ускорил алгоритм:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
int i, r;
const int c(RAND_MAX + 1);
unsigned int m, M, k, R[c], R_count[0x20000+4];
 
void main()
{
    R_count[0] = c;
    do{
        srand(k);
        if(++R_count[r = ++R[rand()]] == 1) M = r;
        if(--R_count[r-1] == 0) m = r;
 
        if( (R_count[r] == c) || !((k+1) << 8))
            cout << "<0x" << hex << k << dec << "> Count RAND(min, max) = ["
                 << m << ", " << M << "]" << ((m == M)?('\n'):('\r'));
    }while(++k);
 
    cout << "\rPress ENTER to continue...";
    cin.get();
}
Итог тот же
Цитата Сообщение от eXPonent Посмотреть сообщение
Итог очень интересный:
Кликните здесь для просмотра всего текста
<0x7fffffff> Count RAND(min, max) = [65536, 65536]
<0xffffffff> Count RAND(min, max) = [131072, 131072]
Press ENTER to continue...
Добавлено через 18 минут
Получается что равномерно распределить значения можно только в двух диапазонах:
[0x00000000..0x7fffffff] и
[0x00000000..0xffffffff] и
и эти диапазоны он трансформирует в [0x0000..0x7fff]

Добавлено через 3 минуты
Получается подобным методом можно шифровать данные!
Правда размер файла итоговый будет в два раза больше
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.05.2017, 21:29
Ответы с готовыми решениями:

Генератор псевдо случайных чисел повторяет значения
Генерирую доступ случайным образом в массив chars; К примеру 1000 раз,...

Псевдо генератор случаных чисел
Доброго времени суток! Вот есть такая прорамка #include &lt;math.h&gt; #include...

Как использовать генератор случайных чисел?
Помогите, пожалуйста, разобраться и исправить программу .Как в этой программе...

Как сделать генератор случайных чисел?
как правильно сделать генератор случайных чисел?? Приведите пожалуйста примеры??

Как написать генератор случайных чисел?
Помогите, пожалуйста, написать такой код! Добавлено через 8 минут Только...

50
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
28.05.2017, 21:55 #2

Не по теме:

Ладно, я невнимательно прочитал сообщение.



Добавлено через 2 минуты
Можешь со своим генератором пробежаться вот по этим тестам.

Добавлено через 5 минут
Цитата Сообщение от eXPonent Посмотреть сообщение
Такое же число NewT может появиться только через ~ 48 дней
Оно способно давать псевдослучайное число каждую ~ миллисекунду
Я вот эти выкладки не понял.
srand вызывается только единожды при инициализации генератора случайных чисел, а дальше вызывается функция rand сколько угодно раз.
Т.е. вот такое:
Цитата Сообщение от eXPonent Посмотреть сообщение
srand(k); if(++R_count[r = ++R[rand()]] == 1) M = r;
вкорне неверно. Никаких более-менее хороших псевдослучайных чисел ты не получишь.

Добавлено через 3 минуты
Цитата Сообщение от eXPonent Посмотреть сообщение
Получается подобным методом можно шифровать данные!
Зашифровать можно что угодно, каким угодно методом. Вопрос только в том на сколько это будет надежно.
1
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 01:42  [ТС] #3
Цитата Сообщение от nonedark2008 Посмотреть сообщение
вкорне неверно. Никаких более-менее хороших псевдослучайных чисел ты не получишь.
Так более понятно что делает алгоритм?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
 
bool TestRAND(const unsigned int i = 0) // i - параметр старта для нового семени
{
    int r; // [0..0x7fff]
    const int c(RAND_MAX + 1); // Кол-во генирируемых чисел rand()
    unsigned int m(0), M, k(i), R[c] = {}, R_count[0x20000+1] = {c}; // 0x20000*c == 0xffffffff + 1
 
    do{
        srand(k);
        if(++R_count[r = ++R[rand()]] == 1) M = r;
        if(--R_count[r-1] == 0) m = r;
 
        if( (R_count[r] == c) || !((k-i+1) << 8))   // Сохраняет равномерные промежутки
            cout << "<0x" << hex << k << dec << "> Count RAND(min, max) = ["
                 << m << ", " << M << "]       " << ((m == M)?('\n'):('\r'));
    }while(++k != i);
    cout << endl; // Необязателен, но желетелен
 
    return R_count[0x20000] == c; // Возвращает false - если не равномерное значение
    // Возвращает true - если равномерное трансформирование [0x00000000..0xffffffff] -> [0x0000..0x7fff]
}
 
void main()
{
    if(TestRAND(2))
        cout << "\nPress ENTER to continue...";
    cin.get();
}
Добавлено через 4 минуты
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Можешь со своим генератором пробежаться вот по этим тестам.
Так я уже вычислил, что только два промежутка равномерно трансформируются (но за ссылку спасибо):
Цитата Сообщение от eXPonent Посмотреть сообщение
Получается что равномерно распределить значения можно только в двух диапазонах:
[0x00000000..0x7fffffff] и
[0x00000000..0xffffffff] и
и эти диапазоны он трансформирует в [0x0000..0x7fff]
В остальных диапазонах не получается равномерное распределение
Хотя я не проверял, если k сдвинуть на единицу

Добавлено через 6 минут
C++
1
rand()
при каждом вызове встряхивает значение
т.е. внутри выполняется
C++
1
srand(псевдо-случайное семя);
Вот только это псевдо-случайное семя зависит от предыдущего семени

Добавлено через 2 минуты
C++
1
2
srand(N); // N - неизменяемое
cout << rand() << rand() << rand();
Сделайте несколько итераций и вы поймёте, что последовательности одни и те же

Добавлено через 41 минуту
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Я вот эти выкладки не понял.
unsigned long (time(NULL) << 10)) = [0x00000000<<10..0xffffffff<<10] с обрубанием старших битов
чисел там 4*194*304 (2^22)
2^22 / 60 секунд / 60 минут / 24 часа ~ 48,545 дней
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Оно способно давать псевдослучайное число каждую ~ миллисекунду
Потому как функция clock(NULL)
возвращает число в миллисекундах (сколько проработала программа),
следовательно каждую миллисекунду там (относительно) новое значение
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 02:23 #4
Цитата Сообщение от eXPonent Посмотреть сообщение
Сделайте несколько итераций и вы поймёте, что последовательности одни и те же
Внутри rand сидит обычный линейный конгруэнтный генератор.
srand просто инициализирует начальное значение этого генератора, вызывая srand каждый раз перед вызовом rand ты только портишь свойства этого генератора.
Я рад, что выдаваемые числа близки к равномерному распределению, но... на сколько они случайны?
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 10:49  [ТС] #5
Вот как этот выглядит у меня в VS2010
C++
1
2
3
4
#include <cruntime.h>
#include <mtdll.h>
#include <stddef.h>
#include <stdlib.h>
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Внутри rand сидит обычный линейный конгруэнтный генератор.
C++
1
2
3
4
5
6
7
8
9
int __cdecl rand (
        void
        )
{
        _ptiddata ptd = _getptd();
 
        return( ((ptd->_holdrand = ptd->_holdrand * 214013L
            + 2531011L) >> 16) & 0x7fff );
}
Цитата Сообщение от nonedark2008 Посмотреть сообщение
srand просто инициализирует начальное значение этого генератора
C++
1
2
3
4
5
6
void __cdecl srand (
        unsigned int seed
        )
{
        _getptd()->_holdrand = (unsigned long)seed;
}
Цитата Сообщение от nonedark2008 Посмотреть сообщение
вызывая srand каждый раз перед вызовом rand ты только портишь свойства этого генератора.
вызывая srand каждый раз (например на машине друга) я ставлю зависимость его скорости процессора, на генирируемость чисел, т.е.
чем быстрее проц, тем ближе будут располагаться семени
чем слабее проц, тем дальше будут располагаться семени
И можно ли это назвать портить алгоритм?
Когда например там, известно последовательность генерируемая тремя последовательными rand()
То у меня все зависит уже от железа

Можно ещё какую-нить зависимость прикрутить
например считывать какой-нить файл
(попросить положить рядом с программой файл, например EXE или BIN)
Как мне кажется, таким образом можно повысить случайность значений
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 11:10 #6
eXPonent, эти все выкладки ничего не стоят.
Цитата Сообщение от eXPonent Посмотреть сообщение
И можно ли это назвать портить алгоритм?
Можно. При фиксированном семени известно, что конгруэнтный генератор выдает последовательность уникальных чисел с периодом T. Какой период будет у тебя? Если брать в расчет худший случай, то период будет 1.
Цитата Сообщение от eXPonent Посмотреть сообщение
Когда например там, известно последовательность генерируемая тремя последовательными
Не понял.
Цитата Сообщение от eXPonent Посмотреть сообщение
То у меня все зависит уже от железа
От датчика времени. Т.е. если злоумышленние знает время генерации сообщения (с некоторой точностью), то ему нужно перебрать примерно пару тысяч значений (условно), чтобы вычислить изначальное семя. Готово, тебя хакнули.

Добавлено через 3 минуты
eXPonent, кстати, а почему ты зациклился на rand?
В C++ есть замечатльный заголовочный файл random - там целая толпа различных алгоритмов для генерации случайных чисел, возможно даже будет настоящий случайный, а не псевдослучайный.
1
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 11:29  [ТС] #7
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Не понял.
Цитата Сообщение от eXPonent Посмотреть сообщение
C++
1
2
srand(N); // N - неизменяемое (время)
cout << rand() << rand() << rand();
Цитата Сообщение от nonedark2008 Посмотреть сообщение
От датчика времени. Т.е. если злоумышленник знает время генерации сообщения (с некоторой точностью), то ему нужно перебрать примерно пару тысяч значений (условно), чтобы вычислить изначальное семя. Готово, тебя хакнули.
Хорошо тогда в твоем варианте тебя хакнут только зная (с точность до секунды)
Цитата Сообщение от nonedark2008 Посмотреть сообщение
если злоумышленник знает время генерации сообщения (с некоторой точностью)
Цитата Сообщение от nonedark2008 Посмотреть сообщение
кстати, а почему ты зациклился на rand?
потому, что для начала неплохо бы изучить базовые алгоритмы, перед тем как в дебри лезть (мне)

Цитата Сообщение от nonedark2008 Посмотреть сообщение
возможно даже будет настоящий случайный
Как мне кажется это невозможно
иначе, почему до сих пор (спустя уже как более 40 как изобрели первые ПСП)
актуальны машины, для генерации случайных последовательностей и стоят они бешенные деньги

Добавлено через 4 минуты
Генерация псевдослучайных чисел

Добавлено через 3 минуты
Цитата Сообщение от nonedark2008 Посмотреть сообщение
о ему нужно перебрать примерно пару тысяч значений (условно), чтобы вычислить изначальное семя. Готово, тебя хакнули.
А вот тут вы не правы
злоумышленник не только должен знать примерное время
но так же когда и сколько раз происходило встряхивание значений
иначе вместо 1000 комбинации ему придется перебрать:
1000^(сколько секунд проработала прога)
0
vndtta
90 / 67 / 21
Регистрация: 17.10.2011
Сообщений: 235
Завершенные тесты: 1
29.05.2017, 11:35 #8
Лучший ответ Сообщение было отмечено eXPonent как решение

Решение

чуваки загляните сюда, там куча прикольных генераторов http://en.cppreference.com/w/cpp/numeric/random
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 11:46 #9
Цитата Сообщение от eXPonent Посмотреть сообщение
Хорошо тогда в твоем варианте тебя хакнут только зная
Зная что?
Цитата Сообщение от eXPonent Посмотреть сообщение
актуальны машины, для генерации случайных последовательностей и стоят они бешенные деньги
А пример можно? Чем твой генератор лучше аналогов? Я не думаю, что имеет смысл вообще сравнивать, ибо и так понятно, что он будет хуже. Также ты не можешь что-либо утверждать для своего генератора, не доказав его математических свойств.

Цитата Сообщение от eXPonent Посмотреть сообщение
неплохо бы изучить базовые алгоритмы
Отличная идея, у Кнута во втором томе как раз имеется глава, посвященная случайным числам.
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 11:49  [ТС] #10
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Зная что?
Я же писал, там внизу написано.
Цитата Сообщение от eXPonent Посмотреть сообщение
Цитата Сообщение от nonedark2008 Посмотреть сообщение
если злоумышленник знает время генерации сообщения (с некоторой точностью)
Цитата Сообщение от nonedark2008 Посмотреть сообщение
А пример можно? Чем твой генератор лучше аналогов? Я не думаю, что имеет смысл вообще сравнивать, ибо и так понятно, что он будет хуже. Также ты не можешь что-либо утверждать для своего генератора, не доказав его математических свойств.
Я не утверждаю, что генератор лучше аналогов
Я лишь выдвинул гипотезу, что:
Цитата Сообщение от eXPonent Посмотреть сообщение
придумал сам, но может где то подобное писалось (просто я не искал)
C++
1
2
unsigned long NewT((unsigned long (time(NULL) << 10)) + (clock()&1023));
srand(NewT);
Лучше, почему?
Такое же число NewT может появиться только через ~ 48 дней
Оно способно давать псевдослучайное число каждую ~ миллисекунду
Такое же случайное число может получиться через ~32,768 секунд

чем обычное
C++
1
srand(time(NULL));
Такое же число time(NULL) не сгенерируется уже никогда (~135 лет)
способно давать псевдослучайное число - каждую секунду
Такое же случайное число может получиться через ~9 часов 6 минут
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 11:52 #11
eXPonent;10489498"]но так же когда и сколько раз происходило встряхивание значений[/quote]
Эмм, встряхиванием ты называешь вызов srand? Сам посмотри на свою формулу, вызов time = зависимость от текущего времени. clock() & 1023 десять бит зависят от времени работы программы. Т.е. если я знаю время, то мне нужно перебрать только оставшиеся 10 бит, т.е. примерно 1000 значений.
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 11:57  [ТС] #12
Без доказательств, но если везде и вся рекомендуют использовать:
C++
1
srand(time(NULL));
То я думаю, потенциальным
Цитата Сообщение от nonedark2008 Посмотреть сообщение
злоумышленникам
сломает мозг использование:
Цитата Сообщение от eXPonent Посмотреть сообщение
C++
1
2
unsigned long NewT((unsigned long (time(NULL) << 10)) + (clock()&1023));
srand(NewT);
Добавлено через 3 минуты
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Эмм, встряхиванием ты называешь вызов srand?
да, именно так

Цитата Сообщение от nonedark2008 Посмотреть сообщение
Т.е. если я знаю время, то мне нужно перебрать только оставшиеся 10 бит, т.е. примерно 1000 значений.
А откуда ты знаешь сколько раз я вызывал в программе srand() и в каких местах?

только если дизамблезировать код

А в стандартных программах, можно предположить что:
C++
1
srand(time(NULL));
вызывается в начале проги, единожды
этому ж везде учат

Добавлено через 15 секунд
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Эмм, встряхиванием ты называешь вызов srand?
да, именно так

Цитата Сообщение от nonedark2008 Посмотреть сообщение
Т.е. если я знаю время, то мне нужно перебрать только оставшиеся 10 бит, т.е. примерно 1000 значений.
А откуда ты знаешь сколько раз я вызывал в программе srand() и в каких местах?

только если дизамблезировать код

А в стандартных программах, можно предположить что:
C++
1
srand(time(NULL));
вызывается в начале проги, единожды
этому ж везде учат
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 12:08 #13
Цитата Сообщение от eXPonent Посмотреть сообщение
Я лишь выдвинул гипотезу
Я подвергаю сомнению верность твоей гипотезы, ибо ты совершенно не разбираешься в вопросе, да и сам подход выглядит как профанация.

Недавно мне довелось поучаствовать в одной студенческой конференции. Там группу ребят должна была выступать со своей новой криптосистемой на замену RSA. Их не допустили до выступления по одной простой причине... После подачи доклада, один из интервьюеров в отзыве написал простенькой математическое доказательство того, почему их система нифига не криптостойкая.

Изучай основы, а уже потом приступай к самостоятельной разработке чего-либо.

Добавлено через 4 минуты
Цитата Сообщение от eXPonent Посмотреть сообщение
только если дизамблезировать код
Это вызывает какие-то трудности?
В криптографии уже давно отказались от алгоритмов, которые основаны только на том, что никто не знает, как они работают. Ибо рано или поздно кто-нибудь да узнает.
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 12:20  [ТС] #14
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Я подвергаю сомнению верность твоей гипотезы, ибо ты совершенно не разбираешься в вопросе, да и сам подход выглядит как профанация.
т.е. ты хочешь сказать, что:
Цитата Сообщение от eXPonent Посмотреть сообщение
C++
1
srand(time(NULL));
устанавливает более рандомное семя, чем?

Цитата Сообщение от eXPonent Посмотреть сообщение
C++
1
2
unsigned long NewT((unsigned long (time(NULL) << 10)) + (clock()&1023));
srand(NewT);
Я правильно тебя понял?

Цитата Сообщение от nonedark2008 Посмотреть сообщение
Изучай основы, а уже потом приступай к самостоятельной разработке чего-либо.
Какой разработке?
Я лишь своими выкладками показал что функция rand() равномерная, на определенных 2-х промежутках
и никаких более (так как можно перебрать все остальные промежутки, моим кодом и убедится)

Добавлено через 3 минуты
Цитата Сообщение от nonedark2008 Посмотреть сообщение
да и сам подход выглядит как профанация
Если это так, тогда приведи математически, чем мой алгоритм подсчета влоб плох
или же чем плохо задействование в рандомизации семени миллисекунд
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 12:30 #15
Цитата Сообщение от eXPonent Посмотреть сообщение
ты хочешь сказать
Я вовсе хочу сказать, что толку от твоего подхода - никакого. Я критикую саму идею и метод ее реализации и проверки.
Цитата Сообщение от eXPonent Посмотреть сообщение
своими выкладками показал
Не показал. Да и показывать это не нужно, открыл учебник, да прочитал про конгруэнтный генератор.

Добавлено через 2 минуты
Цитата Сообщение от eXPonent Посмотреть сообщение
чем мой алгоритм подсчета влоб плох
Ну, я же в самом начале сказал, что при моделировании ты неверно в программе используешь функции srand и rand.
Я вот про такое в цикле:
Цитата Сообщение от eXPonent Посмотреть сообщение
srand(...); rand();
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 12:43  [ТС] #16
Цитата Сообщение от eXPonent Посмотреть сообщение
Я не утверждаю, что генератор лучше аналогов
Я лишь выдвинул гипотезу, что:
Цитата Сообщение от eXPonent Посмотреть сообщение
придумал сам, но может где то подобное писалось (просто я не искал)
C++
1
2
unsigned long NewT((unsigned long (time(NULL) << 10)) + (clock()&1023));
srand(NewT);
Лучше, почему?
Такое же число NewT может появиться только через ~ 48 дней
Оно способно давать псевдослучайное число каждую ~ миллисекунду
Такое же случайное число может получиться через ~32,768 секунд
чем обычное
C++
1
srand(time(NULL));
Такое же число time(NULL) не сгенерируется уже никогда (~135 лет)
способно давать псевдослучайное число - каждую секунду
Такое же случайное число может получиться через ~9 часов 6 минут
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Я подвергаю сомнению верность твоей гипотезы, ибо ты совершенно не разбираешься в вопросе, да и сам подход выглядит как профанация.
На мой взгляд (unsigned long (time(NULL) << 10)) + (clock()&1023)
Дает более равномерное распределение на промежутке [0x00000000..0xffffffff]
чем обычное использование: time(NULL)

Добавлено через 1 минуту
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Ну, я же в самом начале сказал, что при моделировании ты неверно в программе используешь функции srand и rand.
Я вот про такое в цикле:
Это я делал, для перебора всех семян
Что бы узнать какие значения, при каком установочном семени появляются

Добавлено через 6 минут
Я только в этой статье:
Генерация случайных чисел в С++

Нашел вот такое:
Могу посоветовать поэкспериментировать с добавлением в srand() функции clock(), возвращающей приблизительное процессорное время потраченное на работу с программой. Вот такая вот будет строка
C++
1
srand(time(NULL) | clock());
В некоторых случаях возможно получение более случайных величин, хотя, лично я, принципиальной разницы не замечал.
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 12:48 #17
Цитата Сообщение от eXPonent Посмотреть сообщение
Это я делал, для перебора всех семян
Выбрал семя, вызвал rand пару миллиардов раз. И так для всех семян.
Цитата Сообщение от eXPonent Посмотреть сообщение
Дает более равномерное распределение на промежутке
Ты выбрал семя, вызвал один раз rand. По мне так это не показывает ничего, слишком мало статистических данных.
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 12:49  [ТС] #18
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Не показал. Да и показывать это не нужно, открыл учебник, да прочитал про конгруэнтный генератор.
Я перебрал все значения (а в комбинаторике перебор всех возможных вариаций, то же док-во)
изменяя i можно увидеть как сдвигается равномерный промежуток, но при этом их количество обязательно два
размер постоянный и количество элементов внутри, то же постоянно
0
nonedark2008
1025 / 765 / 211
Регистрация: 28.07.2012
Сообщений: 2,127
29.05.2017, 12:53 #19
Цитата Сообщение от eXPonent Посмотреть сообщение
Нашел вот такое:
Да-да, а я предпочитаю использовать time(NULL) ^ pid, где pid - идентификатор текущего процесса.
Цитата Сообщение от eXPonent Посмотреть сообщение
На мой взгляд (unsigned long (time(NULL) << 10)) + (clock()&1023)
Дает более равномерное распределение на промежутке [0x00000000..0xffffffff]
чем обычное использование: time(NULL)
Ты уже определись, что ты проверяешь, случайность выбранного тобой семени, или все же функцию rand().
0
eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 12:59  [ТС] #20
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Выбрал семя, вызвал rand пару миллиардов раз. И так для всех семян.
Именно так, ведь семя типа uINT
т.е. достаточно перебрать (UINT_MAX + 1) семян

Цитата Сообщение от nonedark2008 Посмотреть сообщение
Ты выбрал семя, вызвал один раз rand. По мне так это не показывает ничего, слишком мало статистических данных.
А зачем вызывать много раз rand() ?
когда и так известно, что он устанавливает сам семя, которое зависит от генерируемого числа, т.е.
при одинаковом начальном семени
последовательный вызов
rand() rand() rand()
будет давать одну и ту же последовательность
вне зависимости, где располагаются эти rand() в программе

Добавлено через 1 минуту
Цитата Сообщение от nonedark2008 Посмотреть сообщение
случайность выбранного тобой семени
Так от случайного выбранного семени, зависит rand()
следовательно и случайность генерации rand()

Добавлено через 1 минуту
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Да-да, а я предпочитаю использовать time(NULL) ^ pid, где pid - идентификатор текущего процесса.
можно комбинировать различные варианты реализаций
только вот pid лежит ли в каких то пределах?

Добавлено через 53 секунды
И насколько у него случайный так сказать выпадение числа, при повторном запуске программы
0
29.05.2017, 12:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.05.2017, 12:59

Как создать генератор случайных чисел ?
Доброго всем времени суток. У меня возник вопрос, как создать генератор...

Генератор случайных чисел. Как прикрепить?
Как к генератору случайных чисел прикрепить &quot;Введите размер массива&quot;? #include...

Как создать генератор случайных чисел
Здравствуйте!Я работаю в dev c++ 4.9.9.2 киньте готовый исходник.Зарание...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru