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

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

28.05.2017, 21:29. Показов 13942. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.05.2017, 21:29
Ответы с готовыми решениями:

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

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

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

50
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
29.05.2017, 18:20
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от eXPonent Посмотреть сообщение
например можно поставить отслеживания нажатия Enter на клавиатуре, от начала работы проги
Это будет какое-то жалкое подобие использование клавиатуры для получения энтропии.
Цитата Сообщение от eXPonent Посмотреть сообщение
ты спросил насколько числа случайны
Я реализовал алгоритм
Мда. Случайность каких чисел ты проверяешь? Что за меру случайности ты используешь? Может вероятности расчитываешь, или используешь какую-либо из известных метрик?

Цитата Сообщение от eXPonent Посмотреть сообщение
Ты сам алгоритм понял?
Ага. И пришел к выводу, что твоя программа попросту решает сравнение на заданном интервале значений. В итоге ты узнал, что решением сравнения является некоторая последовательность, задаваемая числами из приведенных тобой скриншотов.
0
 Аватар для eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 18:32  [ТС]
Короче убрав коменты, запустил проги сам
Вот ещё пару скриншотов, для того что бы ты понял
Первый скриншот показывает при каких выполняется тождество
X - любое число из первого скриншота
C++
1
2
srand(x);
rand() == 0; // true!
Второй скрин показывает какая разница, между двумя стоящими рядом числами
т.е. выполняется тождество (T - любое число со второго скрина):
C++
1
2
3
4
5
// (число до T) + T = (число после T)
srand(uint x); 
h=rand();
srand(uint x + T);
(h == rand()) && (h == 0); //true!
В 16-ричной системе дублировать скрины?

Цитата Сообщение от eXPonent Посмотреть сообщение
Обратите внимание на это i = 39
в нем нет уникального первого значения!
Вместо этого количество значений 20069 на один больше во как
Обратил?
Миниатюры
Генератор псевдо-случайных чисел, как хэш-функция   Генератор псевдо-случайных чисел, как хэш-функция  
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
29.05.2017, 18:45
Цитата Сообщение от eXPonent Посмотреть сообщение
Обратил?
Мне если честно уже надоело заниматься этим дебилизмом.
Раз ты рассматриваешь только один вызов rand, то пусть будет функция rand(x), где x - это семя.
Смотри:
у нас есть функция i=rand(x) что равносильно rand(x)-i=0. Ты зафиксировал i, а затем перебрал все x в некотором диапазоне. С помощью этого ты нашел некоторые корни вышеприведенного уравнения. А точнее нашел какую-то периодичность, с которой повторяются эти корни. Зачем? А хрен знает. С ГПСЧ это пока никак не связано.

0
 Аватар для eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
29.05.2017, 18:52  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Мда. Случайность каких чисел ты проверяешь? Что за меру случайности ты используешь? Может вероятности расчитываешь, или используешь какую-либо из известных метрик?
генерируемых функцией rand()
Меру случайности использую за основу разность между двумя соседними семенами
(не читал ни где, сам придумал)
при которых первое генерируемое число одинаковое

Добавлено через 2 минуты
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Раз ты рассматриваешь только один вызов rand
Давай проверим первых два числа, что бы были одинаковы, сейчас сделаю

Добавлено через 3 минуты
Цитата Сообщение от nonedark2008 Посмотреть сообщение
А точнее нашел какую-то периодичность, с которой повторяются эти корни. Зачем? А хрен знает. С ГПСЧ это пока никак не связано.
Так эта периодичность повторяется для ЛЮБОГО I == rand()
разве это нормально?
или таким образом они сделали, что множества не пересекаются?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
29.05.2017, 19:13
Цитата Сообщение от eXPonent Посмотреть сообщение
Давай проверим первых два числа, что бы были одинаковы, сейчас сделаю
Забей, это бестолку. Я не вижу задачи, которую ты пытаешься решить.
Самопридуманный генератор, самопридуманный метод оценки последовательности, с таким подходом можно выиграть что угодно у кого угодно со сколько угодно большим отрывом.

Цитата Сообщение от eXPonent Посмотреть сообщение
разве это нормально?
Потому что такова природа уравнений, которые лежат в основе данного ГПСЧ. Пройди курс дискретной математики и почитай Кнута, а потом уже возвращайся к своим исследованиям.
0
 Аватар для eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 14:19  [ТС]
Функция имеет период:
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
31
32
#include <iostream>
using namespace std;
 
bool Period()
{
    unsigned char t(0);
    unsigned int k(0);
    unsigned short RAND[0x100] = {}; // 256
    cout << hex;
    do{
//      t = 0;
        srand(k);
        do{ RAND[t] = rand(); 
        }while(++t); // Создание последовательности
        
//      t = 0;
        srand(k+0x80000000UL); // Период
        do{ if(RAND[t] != rand()) {cout << dec << endl; return false;}
        }while(++t); // Проверка последовательности
 
        if(!(short)++k) cout << "[0x0 - " <<  "0x" << k-1 << "]\r";
    }while(k != 0x80000000);
 
    cout << dec << endl;
    return true; // Имеет период 
}
 
void main()
{
    if(!Period()) cout << "ERROR\n";
    cin.get();
}
P = 0x80000000UL (это и есть период)
Иными словами, последний 31 бит семени ни на что не влияет

Добавлено через 1 час 16 минут
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Цитата Сообщение от eXPonent Посмотреть сообщение
Получается подобным методом можно шифровать данные!
Правда размер файла итоговый будет в два раза больше
Зашифровать можно что угодно, каким угодно методом. Вопрос только в том на сколько это будет надежно.
Брюс Шнайер. Глава 16. // Прикладная криптография.Триумф.2002. Указ. соч. — С. 275
Хотя линейный конгруэнтный метод порождает статистически хорошую псевдослучайную последовательность чисел, он не является криптографически стойким. Генераторы на основе линейного конгруэнтного метода являются предсказуемыми, поэтому их нельзя использовать в криптографии. Впервые генераторы на основе линейного конгруэнтного метода были взломаны Джимом Ридсом (Jim Reeds), а затем Джоан Бояр (Joan Boyar). Ей удалось также вскрыть квадратические и кубические генераторы. Другие исследователи расширили идеи Бояр, разработав способы вскрытия любого полиномиального генератора. Таким образом, была доказана бесполезность генераторов на основе конгруэнтных методов для криптографии. Однако генераторы на основе линейного конгруэнтного метода сохраняют свою полезность для некриптографических приложений, например, для моделирования. Они эффективны и в большинстве используемых эмпирических тестах демонстрируют хорошие статистические характеристики.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
30.05.2017, 14:27
eXPonent, только стоит учесть, что период конгруэнтного генератора, и период, который нашел ты - это совершенно разные вещи. При этом никто не обязует, что внутри функции rand будет именно конгруэнтный генератор, там может быть все, что душе угодно. Тем более в каждом компиляторе скорее всего какая-то своя реализация этой функции.
0
 Аватар для eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
31.05.2017, 16:01  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
eXPonent, только стоит учесть, что период конгруэнтного генератора, и период, который нашел ты - это совершенно разные вещи.
Это я понимаю, это описано тут:
Однако, тут имеется одно НО: функция rand() — это генератор ПСЕВДОСЛУЧАЙНЫХ чисел с "затравкой", который генерирует последовательность чисел длиной М, в зависимости от затравки.

Особенности таких генераторов:

1. Генератор повторяется, через период, равный М (от этого никуда не деться).
2. Генератор выдаёт одну и ту же последовательность, в зависимости от "затравки", которая устанавливается функцией
C++
1
srand(unsigned int seed);
Т.е. для одной затравки rand() генерирует всегда одну и ту же последовательность(и от этого тоже).

Эти особенности надо учитывать. Таким образом, если в разных объектах одного класса требуется генерировать независимые друг от друга последовательности функция rand() не подходит, потому что оба класса будут получать числа из одной и той же последовательности, длинной М. Если оба объекта будут вызывать rand() одинаковое количество раз, то они получат M/2 чисел, потом генератор начнёт повторяться (соответственно 3 объекта = M/3 чисел, и т.д.)
Можно ещё посмотреть в сторону функции CryptGenRandom, если на win сидите.

А также в сторону библиотеки boost::random

Там же наш спор (сделал реверс сообщений для лучшего восприятия)

Цитата Сообщение от eXPonent Посмотреть сообщение
Допустим это так, но тогда можно встряхнуть два-три раза в середине и в конце
что бы сбить периодичность например
Цитата Сообщение от nonedark2008 Посмотреть сообщение
А я говорю, что много раз встряхивать семя вредно.
Цитата Сообщение от eXPonent Посмотреть сообщение
Я предлагаю внести изменения в генерацию начального семени. Вот и все
Сколько раз встряхивать семя, индивидуальное
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Коэффициенты генератора подбираются так, чтобы у получившейся последовательности
были хорошие статистические свойства (я тебе уже кидал ссылку на вики, где описываются такие свойства).
Ты предлагаешь внести некоторые изменения в метод. При этом говоришь, что он стал лучше,
но не обращаешь внимание на те самые свойства.
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Тем, что ты используешь линейный конгруэнтный метод.
Цитата Сообщение от eXPonent Посмотреть сообщение
и чем же так "непредсказуемый образ" хуже чем
Цитата Сообщение от nonedark2008 Посмотреть сообщение
при фиксированном семени выдает последовательность уникальных чисел с заданным периодом
Добавлено через 34 секунды
Цитата Сообщение от nonedark2008 Посмотреть сообщение
rand хорош тем, что при фиксированном семени выдает последовательность уникальных чисел с заданным периодом
И где это сказано, что подобное есть хорошо?
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Вызывая srand в программе несколько раз, это свойство нарушается непредсказыемым образом
Цитата Сообщение от eXPonent Посмотреть сообщение
Докажи
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Я не вижу смысла в необходимости вызывать srand больше одного раза
в однопоточной программе. Лучше этим ты не сделаешь, только хуже.
Цитата Сообщение от eXPonent Посмотреть сообщение
да, именно так
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Эмм, встряхиванием ты называешь вызов srand?
Цитата Сообщение от eXPonent Посмотреть сообщение
А вот тут вы не правы
злоумышленник не только должен знать примерное время, но так же когда и сколько раз происходило встряхивание значений иначе вместо 1000 комбинации ему придется перебрать:
1000^(сколько секунд проработала прога)
Цитата Сообщение от nonedark2008 Посмотреть сообщение
От датчика времени. Т.е. если злоумышленние знает время генерации сообщения (с некоторой точностью), то ему нужно перебрать примерно пару тысяч значений (условно), чтобы вычислить изначальное семя. Готово, тебя хакнули.
Цитата Сообщение от eXPonent Посмотреть сообщение
вызывая srand каждый раз (например на машине друга) я ставлю зависимость его скорости процессора, на генирируемость чисел, т.е.
чем быстрее проц, тем ближе будут располагаться семени
чем слабее проц, тем дальше будут располагаться семени
И можно ли это назвать портить алгоритм?
Когда например там, известно последовательность генерируемая тремя последовательными rand()
То у меня все зависит уже от железа
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Внутри rand сидит обычный линейный конгруэнтный генератор.
srand просто инициализирует начальное значение этого генератора,
вызывая srand каждый раз перед вызовом rand
ты только портишь свойства этого генератора.
Цитата Сообщение от eXPonent Посмотреть сообщение
srand(N);
// N - неизменяемое
cout << rand() << rand() << rand();

Сделайте несколько итераций и вы поймёте, что последовательности одни и те же

комментируют так:
Вызывать в конструкторе каждый раз функцию srand() нет смысла, т.к. она конечно же поменяет затравку, но опять-таки все объекты будут использовать одну затравку для генерации псевдослучайных чисел. А каждый раз вызывать srand() перед вызовом ранд — не эффективно, да и затравку надо где взять. Использовать время?

C++
1
2
srand( static_cast<unsigned int> time( NULL ) );
x = rand();
Однако функция time() вызвращает время в секундах, сколько миллионов раз вызовется rand() за 1 секунду? Если учесть, что для одной затравки генерируется одна последовательность ПСЧ, то в течение 1 секунды rand() будет возвращать 1 и то же число. То же самое справедливо и для реализаций clock(), которая возвращает миллисекунды.
Добавлено через 6 минут
Спасибо админам за спойлер, а то я что то не догадался

Добавлено через 57 минут
Цитата Сообщение от eXPonent Посмотреть сообщение
Анализируя генератор псевдослучайных чисел
Я пришел к выводу, что (Учитывая что 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 минут
Учитывая:
Цитата Сообщение от eXPonent Посмотреть сообщение
P = 0x80000000UL (это и есть период)
Иными словами, последний 31 бит семени ни на что не влияет
Можно все цифры разделить на 2
Мда уж

Добавлено через 20 часов 31 минуту
Этот код проверяет, есть ли одинаковая генерация https://www.cyberforum.ru/cgi-bin/latex.cgi?\forall Seed \in {0x00000000..0x7fffffff}
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <vector>
#include <iostream>
using namespace std;
 
// Структура данных:
// ((3 bit - rand2) + (3 bit - rand1) + (2 bit - kol)) rand3 не хранится!
unsigned char RAND[0x8000][0x8000];
// 0x0, 0x1, 0x2, 0x3 - кол-во одинаковых комбинаций <rand(), rand()> 
unsigned long Count[0x4];
// Пары с вероятным совпадением <rand(), rand(), rand()>
vector<pair<unsigned short, unsigned short>> Dup;
 
void main()
{
    unsigned int k(0);  unsigned short a, b, c, d;  cout << hex;
    do{
        srand(k);   a = rand(); b = rand(); c = rand();
        d = (c >> 1)&7; // В другом виде оно нам и не нужно
        switch((++RAND[a][b])&3)
        {
            case 1: RAND[a][b] += (d << 2);             break;
            case 2: if((RAND[a][b]>>2) == d) 
                        Dup.push_back(make_pair(a, b));
                    RAND[a][b] += (d << 5);             break;
            case 3: if( (((RAND[a][b]>>2)&7)    == d) 
                      || ((RAND[a][b]>>5)       == d) ) 
                        Dup.push_back(make_pair(a, b)); break;
            default: cerr << "\nInteger overflow [Seed = 0x" << k << ']' << endl; 
        }
 
        if((a > 0x7ffc) && (b > 0x7ffc))
        {
            cout << "0x" << k << "; <0x" << a << ", 0x" << b << ", " << (c>>15) 
                 << ((c>>14)&1) << ((c>>13)&1) << ((c>>12)&1) << ((c>>11)&1)
                 << ((c>>10)&1) << ((c>>9)&1) << ((c>>8)&1) << ((c>>7)&1) 
                 << ((c>>6)&1) << ((c>>5)&1) << ((c>>4)&1) << ((c>>3)&1)
                 << ((c>>2)&1) << (c&1) << '>' << endl;
        }
        if(!(k << 8))  cout << "0x" << k << " <" << (RAND[a][b]&3) << ", 0x"
                            << ((RAND[a][b]>>2)&7) << ", 0x" << (RAND[a][b]>>5)
                            << "> Dup.size = " << Dup.size() << "%  \r";
    }while(++k != 0x80000000UL);
    cout << "0x" << k-1 << " <" << (RAND[a][b]&3) << ", 0x" << ((RAND[a][b]>>2)&7)
         << ", 0x" << (RAND[a][b]>>5) << "> Dup.size = " << Dup.size() << "%  ";
    cout << endl << "Count[RAND[a][b]&3] ...";
 
    a=0;
    do{
        b=0;
    do{ // Счетчик количеств
        ++Count[RAND[a][b]&3];
    }while(++b != 0x8000);
    }while(++a != 0x8000);
 
    if((Count[1] + 2*Count[2] + 3*Count[3]) == 0x80000000UL) cout << "\b\b\bcorrect :)";
    else    cout << "\b\b\berror code: 0x" << Count[1] + 2*Count[2] + 3*Count[3];
 
    cout << endl << "THE END";
    cin.get();
}
CMD
0xc21ba41; <0x7ffd, 0x7ffd, 010111110011000>
0xc603284; <0x7ffd, 0x7ffe, 000110001001111>
0x105049bc; <0x7fff, 0x7ffe, 001011100000100>
0x108ec1ff; <0x7fff, 0x7fff, 011001110111011>
0x1de3c81e; <0x7ffd, 0x7ffd, 001111111100011>
0x21d3df56; <0x7fff, 0x7ffd, 010101010011000>
0x22125799; <0x7fff, 0x7ffe, 000011101001111>
0x3395ed33; <0x7fff, 0x7ffd, 001101011100001>
0x33d46576; <0x7ffe, 0x7fff, 011011110010111>
0x4557fb10; <0x7ffe, 0x7ffd, 000101100101011>
0x45967353; <0x7ffe, 0x7fff, 010011111100000>
0x571a08ed; <0x7ffe, 0x7ffe, 011101101110100>
0x57588130; <0x7ffd, 0x7fff, 001100000101010>
0x68dc16ca; <0x7ffe, 0x7ffe, 010101110111100>
0x691a8f0d; <0x7ffd, 0x7fff, 000100001110011>
0x6d0aa645; <0x7fff, 0x7fff, 001001100101000>
0x7a5fac64; <0x7ffe, 0x7ffd, 011111101010000>
0x7a9e24a7; <0x7ffd, 0x7ffe, 001110000000111>
0x7eccb422; <0x7fff, 0x7fff, 000001101110011>
0x7fffffff <1, 0x7, 0x0> Dup.size = 0x0
Count[RAND[a][b]&3] correct
THE END


Добавлено через 30 минут
Собственно:
Dup.size = 0x0 означает, что такой комбинации нет https://www.cyberforum.ru/cgi-bin/latex.cgi?\forall Seed \in {0x00000000..0x7fffffff}
0
 Аватар для eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
03.06.2017, 17:23  [ТС]
На одном из форумов, нашел статью:
Случайное число, Вопрос чайника

И там сказано:
А сдвиг и без того понятно, зачем. Дело в том, что у линейного конгруэнтного генератора без сдвига, используемого в основе большинства реализаций, младшие n бит имеют период ровно 2n, То есть случайными их никак не назовёшь.
Вообще, лучше было бы делать сдвиг на 17 бит (17=32-15), сдвиг на 16 укорачивает период вдвое (c 232 до 231), но на некоторых процессорах это усложнит реализацию.
Кто нибудь экспериментировал подобным образом?
0
 Аватар для eXPonent
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
05.06.2017, 02:36  [ТС]
Ребят, можете мне объяснить зачем в этой формуле:
Цитата Сообщение от eXPonent Посмотреть сообщение
VS2010 - rand.c
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 );
}
Маска &0x7fff, зачем укорачивать последний бит?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
05.06.2017, 09:44
Цитата Сообщение от eXPonent Посмотреть сообщение
Учитывая что RAND_MAX = 32767
0x7fff = 32767

Добавлено через 2 минуты
Наверно последний бит показывает не самые лучшие статистические свойства, вот от него и избавились.
А еще 32767 - это минимальное значение, требуемое стандартом от функции rand.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.06.2017, 09:44

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

Как сделать генератор случайных чисел?
Привет всем. Возник очередной вопрос за это утро. Как сделать генератор случайных чисел? В учебнике написано так: &quot;Для этого...

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

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

Как создать генератор случайных чисел ?
Доброго всем времени суток. У меня возник вопрос, как создать генератор случайных чисел. Написал такой код: a = rand() +...


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

Или воспользуйтесь поиском по форуму:
51
Ответ Создать тему
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru