Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Random - уникальность ключа, Стандартная ф-ция rand() библиотеки Cи 
V
    Опции темы
loneybibi
Дата 23.6.2011, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Использую стандартную функцию Си rand() для генерации случайных чисел, т.к. в Qt qrand() в описании было указано что это генератор псевдослучайных чисел. Потом прочитал на каком то форуме что стандартная функция Си rand() тоже как бы псевдо случайные числа генерирует. 

1. Подскажите какую функцию лучше использовать?

2. Действительно ли rand() псевдо случайные числа генерирует, если да то я так понимаю что и rand() тоже надо таймером NULL заряжать как и qrand, что бы получать действительно уникальные числа.

3. Как создать действительно уникальное число?

4. Насколько уникальна моя функция генерирования ключа? Я лично создавал 700 тысяч ключей и не было ни одного совпадения... 

Спасибо за ответы ! smile

Код

QString randomUniqueKey()
{
    QString letters="qwertyuiopasdfghjklzxcvbnm";
    QString key;
    key+=letters.at(rand()%25);
    for(int i=0;i<3;++i){
        QVariant tmp=rand()%9;
        key+=tmp.toString();
    }
    key+="-";
    key+=letters.at(rand()%25);
    for(int i=0;i<3;++i){
        QVariant tmp=rand()%9;
        key+=tmp.toString();
    }
    key+="-";
    key+=letters.at(rand()%25);
    for(int i=0;i<3;++i){
        QVariant tmp=rand()%9;
        key+=tmp.toString();
    }
    return(key);
}



--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
triclosan
Дата 23.6.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: нет
Всего: 12



Цитата(loneybibi @  23.6.2011,  14:14 Найти цитируемый пост)
2. Действительно ли rand() псевдо случайные числа генерирует, если да то я так понимаю что и rand() тоже надо таймером NULL заряжать как и qrand, что бы получать действительно уникальные числа.

Да, псевдослучайное. Нужно заряжать каким-нибудь рандом-сидом srand(чего-то там).


Цитата(loneybibi @  23.6.2011,  14:14 Найти цитируемый пост)
3. Как создать действительно уникальное число?

Исходить из действительно случайного фактора, например из питания на ядре процессора и т.п.



PM MAIL   Вверх
borisbn
Дата 23.6.2011, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(loneybibi @  23.6.2011,  14:14 Найти цитируемый пост)
1. Подскажите какую функцию лучше использовать?

вод код ф-ции qrand().
Код

int qrand()
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN)
    SeedStorage *seedStorage = randTLS();
    if (seedStorage) {
        SeedStorageType *pseed = seedStorage->localData();
        if (!pseed) {
            seedStorage->setLocalData(pseed = new SeedStorageType);
            *pseed = 1;
        }
        return rand_r(pseed);
    } else {
        //golbal static seed storage should always exist,
        //except after being deleted by QGlobalStaticDeleter.
        //But since it still can be called from destructor of another
        //global static object, fallback to qrand()
        return rand();
    }
#else
    // On Windows and Symbian srand() and rand() already use Thread-Local-Storage
    // to store the seed between calls
    // this is also valid for QT_NO_THREAD
    return rand();
#endif
}

как видишь, она отличается от Си-шной rand() только под линукс, да и то в части Thread-Local-Storage'а

Цитата(loneybibi @  23.6.2011,  14:14 Найти цитируемый пост)
2. Действительно ли rand() псевдо случайные числа генерирует, если да то я так понимаю что и rand() тоже надо таймером NULL заряжать как и qrand, что бы получать действительно уникальные числа.

Псевдо-случайная последовательность - это когда следующее случайное число зависит от предыдущего, но обратной зависимости нет.
Если не вызывать srand() с уникальным числом (таймер(NULL) - вполне подойдёт), то при следующем запуске твоей программы (не функции, а программы) генератор будет выдавать абсолютно такую же последовательность.

Цитата(loneybibi @  23.6.2011,  14:14 Найти цитируемый пост)
3. Как создать действительно уникальное число?

genGUID или как-то так... погугли "генерация GUID"


Цитата(loneybibi @  23.6.2011,  14:14 Найти цитируемый пост)
4. Насколько уникальна моя функция генерирования ключа? Я лично создавал 700 тысяч ключей и не было ни одного совпадения... 

Если не делать srand(), то после перезапуска программы ты получишь точно такую же последовательность ключей. Это сделано специяально, чтобы удобнее было отлаживаться


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
loneybibi
Дата 23.6.2011, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Т.е. если я в начале функции сделаю вот так:
Код

srand(time(NULL)*rand());

То получу почти настоящие случайные числа ? smile Только генерировать я так понимаю случайное число надо не более одного раза в секунду ? smile

Цитата(borisbn @  23.6.2011,  13:29 Найти цитируемый пост)
Цитата(loneybibi @  23.6.2011,  14:14 )
3. Как создать действительно уникальное число?

genGUID или как-то так... погугли "генерация GUID"


В данный момент использую GUID, но генерирует слишком длинный и сложный ключ! Вот если бы его заставить генерировать ключ как у меня smile)
Просто ключ должен быть читабелен для пользователя обязательно smile


Цитата(triclosan @  23.6.2011,  13:21 Найти цитируемый пост)
Цитата(loneybibi @  23.6.2011,  14:14 )
3. Как создать действительно уникальное число?

Исходить из действительно случайного фактора, например из питания на ядре процессора и т.п.


ну это уже слишком сложный вариант smile 


--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
borisbn
Дата 23.6.2011, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(loneybibi @  23.6.2011,  15:03 Найти цитируемый пост)
То получу почти настоящие случайные числа ?  Только генерировать я так понимаю случайное число надо не более одного раза в секунду ? 

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

srand( time( NULL ) );




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
loneybibi
Дата 23.6.2011, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Цитата

как видишь, она отличается от Си-шной rand() только под линукс, да и то в части Thread-Local-Storage'а

Цитата(loneybibi @  23.6.2011,  14:14 )
2. Действительно ли rand() псевдо случайные числа генерирует, если да то я так понимаю что и rand() тоже надо таймером NULL заряжать как и qrand, что бы получать действительно уникальные числа.

Псевдо-случайная последовательность - это когда следующее случайное число зависит от предыдущего, но обратной зависимости нет.
Если не вызывать srand() с уникальным числом (таймер(NULL) - вполне подойдёт), то при следующем запуске твоей программы (не функции, а программы) генератор будет выдавать абсолютно такую же последовательность.


Насчет "абсолютно такой же последовательности", заметил что на ОС Window да это действительно так что при каждом запуске программы идет такая же последовательность чисел если не зарядить srand(). Но на ОС Linux даже если не заряжать srand() ключи получаются уникальными даже при повторном запуске последовательности не совпадают, и ни одного ключа тоже не совпадает сделал сначала один раз 100 тысяч, перезапустил программу и еще 100 тысяч, совпадений ключа нет.


--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
asmdzen
Дата 23.6.2011, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 28.11.2010

Репутация: нет
Всего: 5



Код

srand(time(NULL)*rand());


думаю автор хотел умножить время на случайное число, но тогда как-то так надо писать:
Код

srand(time(NULL));
srand(time(NULL)*rand());

PM MAIL   Вверх
loneybibi
  Дата 23.6.2011, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Цитата(asmdzen @  23.6.2011,  14:25 Найти цитируемый пост)
думаю автор хотел умножить время на случайное число, но тогда как-то так надо писать:
код C++
1:
2:
srand(time(NULL));
srand(time(NULL)*rand());


Да это и имел ввиду но если srand() можно вызывать только один раз то как я понял так уже не получится ?

Добавлено через 13 минут и 34 секунды
Я уже задумываюсь об QUuid. Генерировать им ключ, из него взять 12 символов взять их по четыре и разделить тире. Что бы было что то на подобии моего ключа на вид, уже ладно что не по маске буква и три цифры.

Но в таком случае QUuid дает полноценно уникальный ключ с использованием шумов процессора или что то подобного или как ?  smile 


--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
asmdzen
Дата 23.6.2011, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 28.11.2010

Репутация: нет
Всего: 5



Цитата(loneybibi @  23.6.2011,  15:27 Найти цитируемый пост)
srand() можно вызывать только один раз

почему же, ведь не стоит же там ограничение на количество вызовов )
PM MAIL   Вверх
borisbn
Дата 23.6.2011, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(loneybibi @  23.6.2011,  15:27 Найти цитируемый пост)
Да это и имел ввиду но если srand() можно вызывать только один раз то как я понял так уже не получится ? 

не то, чтобы не получится, просто нет смысла.

Цитата(loneybibi @  23.6.2011,  15:22 Найти цитируемый пост)
Но на ОС Linux даже если не заряжать srand() ключи получаются уникальными даже при повторном запуске последовательности не совпадают, и ни одного ключа тоже не совпадает сделал сначала один раз 100 тысяч, перезапустил программу и еще 100 тысяч, совпадений ключа нет.

достаточно первые три-четыре проверить... а вообще-то странно, что отличаются рез-ты... у тебя "чистый" проект под линукс ? никакие библиотеки больше не включены ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
loneybibi
Дата 23.6.2011, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Цитата(asmdzen @ 23.6.2011,  14:55)
Цитата(loneybibi @  23.6.2011,  15:27 Найти цитируемый пост)
srand() можно вызывать только один раз

почему же, ведь не стоит же там ограничение на количество вызовов )

Ограничений то на вызов то нет.. просто что из этого получится ... 
Вот borisbn говорит что делать вызов srand() нужно только один раз в программе .. и я так понимаю где то в main.cpp это лучше сделать один раз и все ...

Добавлено через 2 минуты и 44 секунды
Цитата(borisbn @ 23.6.2011,  14:59)
Цитата(loneybibi @  23.6.2011,  15:27 Найти цитируемый пост)
Да это и имел ввиду но если srand() можно вызывать только один раз то как я понял так уже не получится ? 

не то, чтобы не получится, просто нет смысла.

Цитата(loneybibi @  23.6.2011,  15:22 Найти цитируемый пост)
Но на ОС Linux даже если не заряжать srand() ключи получаются уникальными даже при повторном запуске последовательности не совпадают, и ни одного ключа тоже не совпадает сделал сначала один раз 100 тысяч, перезапустил программу и еще 100 тысяч, совпадений ключа нет.

достаточно первые три-четыре проверить... а вообще-то странно, что отличаются рез-ты... у тебя "чистый" проект под линукс ? никакие библиотеки больше не включены ?

Да чистый проект. Подключена только Sql библиотека, я создавал базу что бы записывать туда ключи и проверять на совпадение.


--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
loneybibi
Дата 23.6.2011, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Сделал вот так. Насколько это уникально будет? smile 

Код

QString MainWindow::genU()
{
    return(QUuid::createUuid());
}

QString MainWindow::getK(QString t)
{
    QString tmp=t;
    QString key;
    key+=tmp.at(1);
    key+=tmp.at(2);
    key+=tmp.at(3);
    key+=tmp.at(4);
    key+="-";
    key+=tmp.at(5);
    key+=tmp.at(6);
    key+=tmp.at(7);
    key+=tmp.at(8);
    key+="-";
    key+=tmp.at(10);
    key+=tmp.at(11);
    key+=tmp.at(12);
    key+=tmp.at(13);
    return (key);
}



--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
afiskon
Дата 23.6.2011, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

Репутация: нет
Всего: 4



Вот неплохой генератор. Быстрый и проходит различные статиcтические тесты.

Это сообщение отредактировал(а) afiskon - 23.6.2011, 16:33
PM MAIL WWW   Вверх
math64
Дата 24.6.2011, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Цитата(borisbn @  23.6.2011,  15:59 Найти цитируемый пост)
не то, чтобы не получится, просто нет смысла.

Не только смысла нет, но ещё получится менее случайная последовательность.
Например, если вызвать два раза в течение одной секунды, получишь то же число.
Сташие биты чисел, выдаваемых генераторов более случайны. Поэтому, если нужно число в пределах 0...n-1 вместо 
Код
inline int nextRand(int n) { return n <= 0 ? 0 : rand() % n; }

лучше использовать
Код
inline int nextRand(int n) { return n <= 0 ? 0 : (int)((n + 0ULL) * rand()/(RAND_MAX + 1ULL)); }


Цитата(loneybibi @  23.6.2011,  15:22 Найти цитируемый пост)
заметил что на ОС Window да это действительно так что при каждом запуске программы идет такая же последовательность чисел если не зарядить srand(). Но на ОС Linux даже если не заряжать srand() ключи получаются уникальными даже при повторном запуске последовательности не совпадают

В Linux srand() вызывется автоматически до вызова main(). Но если использовать qrand(), то нужно вызвать qsrand() в любом случае.
PM   Вверх
borisbn
Дата 24.6.2011, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(math64 @  24.6.2011,  09:03 Найти цитируемый пост)
В Linux srand() вызывется автоматически до вызова main()

и что, это никак нельзя отменить ? а как же отлаживать проект ? например, сгенерил ты последовательность, на которой программа падает. при след. запуске она уже не упадёт. вот и думай - из-за того, что ты что-то изменил, или просто последовательность данных не приводит к падению...
можно, конечно каждый раз записывать последовательность в файл, и, если упала, "проигрывать" его, но имхо это ужасный изврат. как-то в венде "честнее" сделано...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0589 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.