С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970
|
Добавлено: 14/07/12 в 16:20 |
Нужен алгоритм постоянного уникального набора случайных символов. Как правильно обозвать не знаю
Суть: имеем ключ, допустим 1. Алгоритм генерируют массив из 100 уникальных элементов случайным образом. Что-то вроде shuffle(range(0,99))
При ключе 2 - алгоритм генерирует массив, который сильно отличается от того, что с ключом 1 (т.н. лавинный эффект)
Если снова задать ключ 1 - сгенерируются точно такой же массив, как в первой случае. Т.е. значения распределяются случайным образом, но в жёсткой зависимости от ключа.
Смотрел на хэш-функции, но там возвращается неуникальный набор символов/значений.
Подскажите хотя бы направление, в каком искать. Но лучше готовую функцию
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 14/07/12 в 16:48 |
по хорошему надо инициализировать генератор случайных чисел твоим ключом.
однако насколько я знаю в пхп функции типа mt_srand($seed) перестали давать одинаковые последовательности при одинаковом ключе.
поэтому приходится делать это ручками. пока сходу не нашел готового, пойду завтракать, дальше посмотрим
|
|
|
|
С нами с 24.05.09
Сообщения: 1788
Рейтинг: 508
|
Добавлено: 14/07/12 в 18:13 |
соленый md5 - не вариант?
вообще я нуб в таких алго, но md5(salt,signature) - первое, что пришло в голову
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 14/07/12 в 19:54 |
gimcnuk писал: | алгоритм постоянного уникального набора случайных символов |
Код: | class set {
public static function create( $keys, $length ) {
$set = array();
foreach( $keys as $key )
for( $i = 0; $i < $length; $i += 1 )
$set[ $key ][] = uniqid( md5( mt_rand() ) );
return $set;
}
}
$set = set::create( array( 'one', 'two' ), 10 );
var_dump( $set ); |
|
|
|
|
www.phpdevs.com
С нами с 24.10.02
Сообщения: 16633
Рейтинг: 16105
|
Добавлено: 14/07/12 в 20:28 |
честно говоря вообще не понял, что необходимо. "постоянная" и "случайность" - это полностью противоположные понятия.
Цитата: | Смотрел на хэш-функции, но там возвращается неуникальный набор символов/значений. |
надо очень постараться, что бы получить одинаковые хеши от разных строк.
md5(uniqid().microtime(true)) по идее должен всегда давать разный хеш.
|
|
Пишу на php/mysql/django за вменяемые деньги.
Обращаться в личку.
|
8
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 14/07/12 в 21:36 |
Yacc: у тебя в основе лежит mt_rand что означает при каждом новом вызове функции будет возвращать разную последовательность.
|
|
|
|
С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134
|
Добавлено: 14/07/12 в 23:55 |
обычный мд5, пусть с солью, вполне покроет вопрос, даже голову греть не стоит
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 14/07/12 в 23:59 |
freeek писал: | обычный мд5, пусть с солью, вполне покроет вопрос |
мд5 32 символа выдает тока, дальше надо мутить еще че-то с ним
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 15/07/12 в 01:49 |
grozny писал: | Yacc: у тебя в основе лежит mt_rand что означает при каждом новом вызове функции будет возвращать разную последовательность. |
Зачем новый вызов? Нужен ведь "постоянный уникальный набор". Один раз создал и пользуйся.
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 15/07/12 в 03:19 |
Yacc писал: | Один раз создал и пользуйся. |
а, понял.. ну эт как-то некошерно если по-хорошему делать
обычно надо при любом вызове скрипта одни и те же данные генерить. удобная фича и часто используемая в более простом виде типа crc32($_SERVER['REQUEST_URI']) для одного уникального значения.
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 15/07/12 в 11:29 |
grozny писал: | как-то некошерно если по-хорошему делать |
По-другому никак.
|
|
|
|
С нами с 03.02.11
Сообщения: 842
Рейтинг: 301
|
Добавлено: 15/07/12 в 11:37 |
gimcnuk писал: | Что-то вроде shuffle(range(0,99)) |
что-то вроде генерится так:
Код: | mt_srand(crc32($_YOUR_KEY)); //инициализируем мт твоим ключем
for($i=0; $i<100; $i++) //ну, допустим 100 итераций...
$rnd_arr[] = mt_rand(0, 100); //каждый последующий вызов мт_ранд будет генерить "случайное" число, их последовательность будет постоянна в зависимости от ключа. |
хотя так результаты будут не уникальными... такое больше юзают, когда надо, например, постоянные "случайные" ссылки выводить на странице из базы... вообщем, гоню. не доперепонял задачу...
|
|
|
|
С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970
|
Добавлено: 15/07/12 в 11:48 |
Всем навешал, но решения пока нет. Абыдно, да
Yacc писал: | Один раз создал и пользуйся |
Ну, дык, с тем же успехом можно запускать упомянутый shuffle(range(0,99)) и записывать результаты, кэшировать.
Stek писал: | надо очень постараться, что бы получить одинаковые хеши от разных строк |
Хэши разные, но символы в них повторяются, а нужен набор неповторяющихся значений.
AWD: алгоритм хороший, только с повторами
|
|
|
|
С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970
|
Добавлено: 15/07/12 в 11:49 |
AWD писал: | такое больше юзают, когда надо, например, постоянные "случайные" ссылки выводить на странице из базы... |
Ты раскрыл мой план
|
|
|
|
С нами с 03.02.11
Сообщения: 842
Рейтинг: 301
|
Добавлено: 15/07/12 в 11:55 |
тогда вот, берем то, что написал Yacc:, добавляем инициализацию мт_сранд-а и убиваем уникайди Код: | class set {
public static function create( $keys, $length ) {
$set = array();
foreach( $keys as $key ) {
mt_srand(crc32($key));
for( $i = 0; $i < $length; $i += 1 )
$set[ $key ][] = md5(mt_rand());
}
return $set;
}
}
$set = set::create( array( 'one', 'two' ), 10 );
var_dump( $set );
|
так работает
или если надо цифры в диапазоне выводить, то вот класс Код: | class set {
public static function create( $keys, $length ) {
$set = array();
foreach( $keys as $key ) {
$range = range(0, 99); //тут диапазон
mt_srand(crc32($key));
for( $i = 0; $i < $length; $i++) {
$rnd = mt_rand(0, count($range)-1);
$set[$key][] = $range[$rnd];
unset($range[$rnd]);
}
}
return $set;
}
}
|
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 15/07/12 в 17:09 |
gimcnuk писал: | Ну, дык, с тем же успехом можно запускать упомянутый shuffle(range(0,99)) и записывать результаты, кэшировать. |
Нет. Так будет не уникально и не криптостойко.
gimcnuk писал: | решения пока нет |
Озвучь задачу как она есть, а не так как ты её видишь, тогда и решение будет.
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 15/07/12 в 20:13 |
AWD писал: | тогда вот, берем то, что написал Yacc:, добавляем инициализацию мт_сранд-а и убиваем уникайди |
покурите мануал на сайте пхп, сранд давно уже выдает рандомную последовательность, начиная с какой-то там версии пхп.
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 15/07/12 в 20:21 |
gimcnuk: ладно, вот готовый вариант, все что тут предлагали херня
Код: | function getarray($key, $count, $limit = 10000)
{
$res = array();
do
{
$res []= (int) (abs(crc32($key)) / 2147483647 * $limit);
$key = crc32($key);
} while(count($res) < $count);
return $res;
}
|
getarray(1, 50) всегда возвращает одинаковую рандомную последовательность из 50 чисел.
getarray(2, 50) всегда возвращает другую, но постоянную рандомную последовательность.
$limit - максимальный член последовательности, какой тебе нужен.
|
|
|
|
С нами с 03.02.11
Сообщения: 842
Рейтинг: 301
|
Добавлено: 16/07/12 в 09:20 |
grozny писал: | покурите мануал на сайте пхп, сранд давно уже выдает рандомную последовательность, начиная с какой-то там версии пхп. |
покурил мануал на сайте пхп. Цитата: | При том же параметре последовательность значений будет отличатся от последовательности, сгенерированной в предыдущих версиях PHP |
то есть, на пхп 5.2.1 и выше последовательность будет _другой_, нежели на предыдущих версиях, но никак не рандомной.
и вдогонку - задача стояла генерить _неповторяющиеся_ последовательности, а твой код дает повторения... думал двумя строчками отделаться?
можно, конечно, сделать проверку in_array Код: | do
{
$tmp = (int) (abs(crc32($key)) / 2147483647 * $limit);
if(!in_array($tmp, $res))
$res[] = $tmp;
$key = crc32($key);
} while(count($res) < $count);
|
но нет никакой гарантии, что в один момент все это дело переклинит, ибо начнет генерить повторяющиеся данные... особенно, если лимит 1000, а значений нужно 999 - скорость генерации падает в ~10 раз c ~0,03 до ~0,2сек... ну это так, пример, а вообще, мало-ли, какой сид посеешь, что вообще машину положит, патамушта 48. нет, мало, лучше 49 ... не считаю твой вариант (да и свой) идеальным
|
|
|
|
С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970
|
Добавлено: 16/07/12 в 11:05 |
Yacc писал: | Нет. Так будет не уникально и не криптостойко. |
Криптостойкость совсем не нужна, а вот почему неуникально-то?
Цитата: |
Озвучь задачу как она есть, а не так как ты её видишь, тогда и решение будет. |
AWD: уже догадался. Имеется н-ное количество страниц. Нужно для каждой страницы генерировать случайный набор неповторяющихся ссылок. Причём при каждом заходе на конкретную страницу, набор должен быть одним и тем же, с неизменным порядком ссылок.
Вариант с кешированием shuffle(range(0,99)) как раз подходит, но не нравится кеширование. Хотелось бы при перетаскивании с сервера на сервер забирать только алгоритм, а не таскать весь кеш. Ну и на разных сереверах чтоб выдавались одни и те же наборы. Как-то так.
|
|
|
|
С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538
|
Добавлено: 16/07/12 в 15:14 |
gimcnuk писал: | Криптостойкость совсем не нужна, а вот почему неуникально-то? |
Для твоей задачи достаточно уникально:
Код: | function shuffle_by_key( $key, $arr ) {
srand( $key );
shuffle( $arr );
return $arr;
}
$arr = range( 1, 5 );
foreach( range( 1, 2 ) as $key ) {
var_dump( shuffle_by_key( $key, $arr ) );
var_dump( shuffle_by_key( $key, $arr ) );
} |
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 17/07/12 в 21:03 |
AWD писал: | то есть, на пхп 5.2.1 и выше последовательность будет _другой_, нежели на предыдущих версиях, но никак не рандомной.
и вдогонку - задача стояла генерить _неповторяющиеся_ последовательности, а твой код дает повторения... думал двумя строчками отделаться? |
вот жеж бля.. кажется и правда mt_srand работает
а помнится вроде был косяк с этим какой-то... хз может и не в этом дело было
|
|
|
|
Чингачгук, вождь красноглазых
С нами с 14.05.04
Сообщения: 4744
Рейтинг: 1824
|
Добавлено: 18/07/12 в 00:32 |
gimcnuk писал: |
Вариант с кешированием shuffle(range(0,99)) как раз подходит, но не нравится кеширование. Хотелось бы при перетаскивании с сервера на сервер забирать только алгоритм, а не таскать весь кеш. Ну и на разных сереверах чтоб выдавались одни и те же наборы. Как-то так. |
А точно не нужно, чтобы это быстро работало?
А то ж на каждой странице, да при каждом заходе, да много вычислений...
|
|
|
|
С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506
|
Добавлено: 18/07/12 в 01:57 |
кстати для схожих задач, когда например для страницы надо выбрать рандомом 100 записей из одной таблицы в БД, иногда полезно физически отсортить таблицу в mysql по рандому, это делается однократно а далее просто селектишь последовательно записи 0-100, 100-200 сразу пачкой.
|
|
|
|
С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970
|
Добавлено: 18/07/12 в 10:23 |
Dr.Syshalt писал: | А точно не нужно, чтобы это быстро работало? |
В конечном итоге будет кешироваться вся страница, так что: it's alright, it's ok, it's an odyssee, dr. Mabuse, dr. Mabuse
|
|
|
|