Реклама на сайте Advertise with us

Алгоритм постоянной случайности

Расширенный поиск по форуму
 
Новая тема Новая тема   
Автор
Поиск в теме:



С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970

Ссылка на сообщениеДобавлено: 14/07/12 в 16:20       Ответить с цитатойцитата 

Нужен алгоритм постоянного уникального набора случайных символов. Как правильно обозвать не знаю icon_smile.gif

Суть: имеем ключ, допустим 1. Алгоритм генерируют массив из 100 уникальных элементов случайным образом. Что-то вроде shuffle(range(0,99))
При ключе 2 - алгоритм генерирует массив, который сильно отличается от того, что с ключом 1 (т.н. лавинный эффект)
Если снова задать ключ 1 - сгенерируются точно такой же массив, как в первой случае. Т.е. значения распределяются случайным образом, но в жёсткой зависимости от ключа.

Смотрел на хэш-функции, но там возвращается неуникальный набор символов/значений.

Подскажите хотя бы направление, в каком искать. Но лучше готовую функцию icon_cool.gif

2
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 14/07/12 в 16:48       Ответить с цитатойцитата 

по хорошему надо инициализировать генератор случайных чисел твоим ключом.
однако насколько я знаю в пхп функции типа mt_srand($seed) перестали давать одинаковые последовательности при одинаковом ключе.
поэтому приходится делать это ручками. пока сходу не нашел готового, пойду завтракать, дальше посмотрим icon_smile.gif

8
 



С нами с 24.05.09
Сообщения: 1788
Рейтинг: 508

Ссылка на сообщениеДобавлено: 14/07/12 в 18:13       Ответить с цитатойцитата 

соленый md5 - не вариант?
вообще я нуб в таких алго, но md5(salt,signature) - первое, что пришло в голову smail54.gif

---

8
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 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 );

8
 

www.phpdevs.com

С нами с 24.10.02
Сообщения: 16633
Рейтинг: 16105


Передовик Master-X (01.09.2005) Передовик Master-X (16.09.2005) Передовик Master-X (01.10.2005) Передовик Master-X (16.08.2006) Передовик Master-X (16.10.2006) Ветеран трепа Master-X ()
Ссылка на сообщениеДобавлено: 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 что означает при каждом новом вызове функции будет возвращать разную последовательность.

8
 



С нами с 05.05.05
Сообщения: 1913
Рейтинг: 1134

Ссылка на сообщениеДобавлено: 14/07/12 в 23:55       Ответить с цитатойцитата 

обычный мд5, пусть с солью, вполне покроет вопрос, даже голову греть не стоит

8
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 14/07/12 в 23:59       Ответить с цитатойцитата 

freeek писал:
обычный мд5, пусть с солью, вполне покроет вопрос

мд5 32 символа выдает тока, дальше надо мутить еще че-то с ним

8
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 15/07/12 в 01:49       Ответить с цитатойцитата 

grozny писал:
Yacc: у тебя в основе лежит mt_rand что означает при каждом новом вызове функции будет возвращать разную последовательность.

Зачем новый вызов? Нужен ведь "постоянный уникальный набор". Один раз создал и пользуйся.

8
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 15/07/12 в 03:19       Ответить с цитатойцитата 

Yacc писал:
Один раз создал и пользуйся.

а, понял.. ну эт как-то некошерно если по-хорошему делать icon_smile.gif
обычно надо при любом вызове скрипта одни и те же данные генерить. удобная фича и часто используемая в более простом виде типа crc32($_SERVER['REQUEST_URI']) для одного уникального значения.

8
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 15/07/12 в 11:29       Ответить с цитатойцитата 

grozny писал:
как-то некошерно если по-хорошему делать

По-другому никак. icon_smile.gif

8
 



С нами с 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); //каждый последующий вызов мт_ранд будет генерить "случайное" число, их последовательность будет постоянна в зависимости от ключа.
хотя так результаты будут не уникальными... icon_rolleyes.gif такое больше юзают, когда надо, например, постоянные "случайные" ссылки выводить на странице из базы... вообщем, гоню. не доперепонял задачу...

8
 



С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970

Ссылка на сообщениеДобавлено: 15/07/12 в 11:48       Ответить с цитатойцитата 

Всем навешал, но решения пока нет. Абыдно, да icon_sad.gif

Yacc писал:
Один раз создал и пользуйся

Ну, дык, с тем же успехом можно запускать упомянутый shuffle(range(0,99)) и записывать результаты, кэшировать.

Stek писал:
надо очень постараться, что бы получить одинаковые хеши от разных строк

Хэши разные, но символы в них повторяются, а нужен набор неповторяющихся значений.

AWD: алгоритм хороший, только с повторами icon_sad.gif

0
 



С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970

Ссылка на сообщениеДобавлено: 15/07/12 в 11:49       Ответить с цитатойцитата 

AWD писал:
такое больше юзают, когда надо, например, постоянные "случайные" ссылки выводить на странице из базы...

Ты раскрыл мой план icon_smile.gif

0
 



С нами с 03.02.11
Сообщения: 842
Рейтинг: 301

Ссылка на сообщениеДобавлено: 15/07/12 в 11:55       Ответить с цитатойцитата 

тогда вот, берем то, что написал Yacc:, добавляем инициализацию мт_сранд-а и убиваем уникайди icon_biggrin.gif
Код:
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 );
так работает icon_biggrin.gif
или если надо цифры в диапазоне выводить, то вот класс
Код:
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;
  }
}

8
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 15/07/12 в 17:09       Ответить с цитатойцитата 

gimcnuk писал:
Ну, дык, с тем же успехом можно запускать упомянутый shuffle(range(0,99)) и записывать результаты, кэшировать.

Нет. Так будет не уникально и не криптостойко.

gimcnuk писал:
решения пока нет

Озвучь задачу как она есть, а не так как ты её видишь, тогда и решение будет.

8
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 15/07/12 в 20:13       Ответить с цитатойцитата 

AWD писал:
тогда вот, берем то, что написал Yacc:, добавляем инициализацию мт_сранд-а и убиваем уникайди

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

8
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 15/07/12 в 20:21       Ответить с цитатойцитата 

gimcnuk: ладно, вот готовый вариант, все что тут предлагали херня smail101.gif

Код:
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 - максимальный член последовательности, какой тебе нужен.

8
 



С нами с 03.02.11
Сообщения: 842
Рейтинг: 301

Ссылка на сообщениеДобавлено: 16/07/12 в 09:20       Ответить с цитатойцитата 

grozny писал:
покурите мануал на сайте пхп, сранд давно уже выдает рандомную последовательность, начиная с какой-то там версии пхп.
покурил мануал на сайте пхп.
Цитата:
При том же параметре последовательность значений будет отличатся от последовательности, сгенерированной в предыдущих версиях PHP
то есть, на пхп 5.2.1 и выше последовательность будет _другой_, нежели на предыдущих версиях, но никак не рандомной.
и вдогонку - задача стояла генерить _неповторяющиеся_ последовательности, а твой код дает повторения... думал двумя строчками отделаться? icon_smile.gif
можно, конечно, сделать проверку 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 smail101.gif ... не считаю твой вариант (да и свой) идеальным icon_biggrin.gif

8
 



С нами с 01.04.07
Сообщения: 4378
Рейтинг: 2970

Ссылка на сообщениеДобавлено: 16/07/12 в 11:05       Ответить с цитатойцитата 

Yacc писал:
Нет. Так будет не уникально и не криптостойко.

Криптостойкость совсем не нужна, а вот почему неуникально-то?

Цитата:

Озвучь задачу как она есть, а не так как ты её видишь, тогда и решение будет.

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

Вариант с кешированием shuffle(range(0,99)) как раз подходит, но не нравится кеширование. Хотелось бы при перетаскивании с сервера на сервер забирать только алгоритм, а не таскать весь кеш. Ну и на разных сереверах чтоб выдавались одни и те же наборы. Как-то так.

0
 



С нами с 09.03.09
Сообщения: 6053
Рейтинг: 3538


Передовик Master-X (01.11.2009) Передовик Master-X (16.11.2009) Передовик Master-X (01.02.2011) Передовик Master-X (01.12.2011) Передовик Master-X (16.12.2011) Ветеран трепа Master-X (01.01.2014)
Ссылка на сообщениеДобавлено: 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 ) );
}

icon_smile.gif

8
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 17/07/12 в 21:03       Ответить с цитатойцитата 

AWD писал:
то есть, на пхп 5.2.1 и выше последовательность будет _другой_, нежели на предыдущих версиях, но никак не рандомной.
и вдогонку - задача стояла генерить _неповторяющиеся_ последовательности, а твой код дает повторения... думал двумя строчками отделаться?

вот жеж бля.. кажется и правда mt_srand работает smail54.gif
а помнится вроде был косяк с этим какой-то... хз может и не в этом дело было

8
 

Чингачгук, вождь красноглазых

С нами с 14.05.04
Сообщения: 4744
Рейтинг: 1824

Ссылка на сообщениеДобавлено: 18/07/12 в 00:32       Ответить с цитатойцитата 

gimcnuk писал:

Вариант с кешированием shuffle(range(0,99)) как раз подходит, но не нравится кеширование. Хотелось бы при перетаскивании с сервера на сервер забирать только алгоритм, а не таскать весь кеш. Ну и на разных сереверах чтоб выдавались одни и те же наборы. Как-то так.


А точно не нужно, чтобы это быстро работало?

А то ж на каждой странице, да при каждом заходе, да много вычислений...

8
 



С нами с 27.09.03
Сообщения: 5454
Рейтинг: 2506

Ссылка на сообщениеДобавлено: 18/07/12 в 01:57       Ответить с цитатойцитата 

кстати для схожих задач, когда например для страницы надо выбрать рандомом 100 записей из одной таблицы в БД, иногда полезно физически отсортить таблицу в mysql по рандому, это делается однократно а далее просто селектишь последовательно записи 0-100, 100-200 сразу пачкой.

8
 



С нами с 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

0
 
Новая тема Новая тема   

Текстовая реклама в форме ответа
Заголовок и до четырех строчек текста
Длина текста до 350 символов
Купить рекламу в этом месте!


Перейти:  



Спонсор раздела Стань спонсором этого раздела!

Реклама на сайте Advertise with us

Опросы

Рецепт новогоднего блюда 2022



Обсудите на форуме обсудить (11)
все опросы »