PHP программирование →
Как работает rand?
Столкнулся с задачкой генерации логинов. Недолго думая была написана такая функция:
private function _get_login() {
$login = "";
for( $i=0; $i<=9; $i++ ) {
$login .= chr( rand( 97, 122 ) );
}
return $login;
}
Которая по моему скромному мнению должна была генерировать уникальные логины, которые живому человеку придумать тяжело. Упор ставился именно на уникальность.
Если посчитать, количество таких логинов примерно 141167095653376. Логины генерировались и вставлялись в БД. Каково же было моё удивление когда после генерации примерно 1000 логинов посыпались ошибки добавления в базу при срабатывании констрейнтов не уникальности данных. Причем ошибки не единичные, а десятки логинов подряд вылетали. Начал исследовать — выяснилось эта функция действительно генерирует повторяющиеся логины=\. Как такое может быть, что бы последовательности из 10 случайных чисел совпадали так часто? Ответа на этот вопрос так и не нашел. Перешел на использование функции mt_rand(), которая работает в 4 раза быстрее обычной rand(), имеет какие-то известные гарантированные характеристики работы(в отличии от rand()) и добавил элементарную проверку.
Получилось так:
private function _get_login() {
$done = false;
while( !$done ) {
$login = "";
for( $i=0; $i<=9; $i++ ) {
$login .= chr( mt_rand( 97, 122 ) );
}
$sql = "SELECT count(*) FROM users WHERE login='$login'";
if($this->db->fetchRow( $sql ) == 0)
$done = true;
}
return $login;
}
Может у вас будут идеи по усовершенствованию алгоритма генерации логинов что бы они удовлетворяли следующим условиям:
-более-менее удобочитаемы, а не что-то невнятное вида qlgkakxwci
-более-менее уникальные — что-то типа qlgkakxwci =)
Спасибо за внимание.
private function _get_login() {
$login = "";
for( $i=0; $i<=9; $i++ ) {
$login .= chr( rand( 97, 122 ) );
}
return $login;
}
Которая по моему скромному мнению должна была генерировать уникальные логины, которые живому человеку придумать тяжело. Упор ставился именно на уникальность.
Если посчитать, количество таких логинов примерно 141167095653376. Логины генерировались и вставлялись в БД. Каково же было моё удивление когда после генерации примерно 1000 логинов посыпались ошибки добавления в базу при срабатывании констрейнтов не уникальности данных. Причем ошибки не единичные, а десятки логинов подряд вылетали. Начал исследовать — выяснилось эта функция действительно генерирует повторяющиеся логины=\. Как такое может быть, что бы последовательности из 10 случайных чисел совпадали так часто? Ответа на этот вопрос так и не нашел. Перешел на использование функции mt_rand(), которая работает в 4 раза быстрее обычной rand(), имеет какие-то известные гарантированные характеристики работы(в отличии от rand()) и добавил элементарную проверку.
Получилось так:
private function _get_login() {
$done = false;
while( !$done ) {
$login = "";
for( $i=0; $i<=9; $i++ ) {
$login .= chr( mt_rand( 97, 122 ) );
}
$sql = "SELECT count(*) FROM users WHERE login='$login'";
if($this->db->fetchRow( $sql ) == 0)
$done = true;
}
return $login;
}
Может у вас будут идеи по усовершенствованию алгоритма генерации логинов что бы они удовлетворяли следующим условиям:
-более-менее удобочитаемы, а не что-то невнятное вида qlgkakxwci
-более-менее уникальные — что-то типа qlgkakxwci =)
Спасибо за внимание.




ЗЫ линух сейвит последнее значение.
2. По поводу того «странно чему учат» — я написал свои наблюдения в особенностях поведения функции rand() в php. То что числа псевдослучайные мы тоже проходили. Я просто не догадывался до какой степени они могут быть псевдослучайны.
3. Не против посмотреть вашу версию рендома которая работает лучше php-шной.
4. У меня винда.
во-первых, завтра в шапке повешу «ХУЙ»
во-вторых, это не блог, если ты не заметил
в-третьих, задумывалось для того что бы люди делились опытом
в-четвертых, умного ты нихуя не сказал, а блеснул тем, что вы когда-то там учили, только толку от этого мало
P.S. действительно, покажи, что ты умеешь писать:)
блог не блог, странное деление опытом, или точнее опыт «научного тыка»… :)
я и не собирался ниче умного говорить — на понт брать бесполезно. Это как-бы не я пишу уникальные логины.
хеш функции чем не устраивают? ну возьми рандом, время и логин юзера для хеша. чем не уникальный ид?? а придумывать свои алгоритмы генерения псевдослучайностей — нах надо, сначала стандартные изучайте, а потом уже можно дорабатывать. Эти формулы известны уже много лет, думаете их так просто переделать? я лучше алгоритмы аналитики автобаланса для БФ2 буду писать.
P.S. линух на серваке — он сейвит значение при выключении компа, и оно там как-бы глобально. А вот винде пох. для нее каждая прога заного генерит значения. — это просто пример как можно сделать значения более случайными.
private function _get_login() {
$login = "";
for( $i=0; $i<=9; $i++ ) {
$login .= chr( rand( 97, 122 ) );
}
return $login;
}
Которая по моему скромному мнению должна была генерировать уникальные логины, которые живому человеку придумать тяжело. Упор ставился именно на уникальность.
Если посчитать, количество таких логинов примерно 141167095653376
ыыы Очень смешно.
По моим подсчётам этот код может генерировать 25 тупых логинов
function getLogin($number)
{
// Генерируем пароль
$login = “»;
for($i = 0; $i < $number; $i++)
{
$r = mt_rand(0,2);
switch($r){
case 1: $login .= chr( mt_rand( 97, 122 ) ); break;
case 2: $login .= chr( mt_rand( 65, 90 ) ); break;
default: $login .= chr( mt_rand( 49, 57 ) ); break;
}
}
return $login;
}
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста, или зарегистрируйтесь, если не зарегистрированы.