Функция рандомизации

Тема в разделе "PHP", создана пользователем Levitt, 10 янв 2012.

Модераторы: latteo
  1. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    358
    Симпатии:
    36
    Подскажите есть ли в наборе или простую функцию в которой перемешиние массива зависила бы от заданного ключа.
    Т.е. имеем масив (1,2,3,4,5,6,7,8,9)
    запускаем некая_функция (массив, 91841);
    и получали бы в результате все время 4,7,9,3,1,2,5,6,8
    некая_функция (массив, 2011); -> 8,4,6,7,9,1,2,3,5
    ...
     
  2. a_n_d_y

    a_n_d_y

    Регистр.:
    26 мар 2006
    Сообщения:
    465
    Симпатии:
    61
    И где тут рандомизация если нужно отсортировать именно в определенном и известном порядке?
    А из примера не понятно, что именно означает ключ. Или он здесь от фанаря?
     
  3. Nellisen

    Nellisen Постоялец

    Регистр.:
    4 авг 2008
    Сообщения:
    54
    Симпатии:
    8
    Это получается уже небольшая криптовка :)
    Возможно подойдет Перейти по ссылке.
    Но мне кажется проще всего здесь будет использовать Перейти по ссылке. Ведь на выходе вам нужны тоже цифры?
     
  4. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    хм, если человеку нужно именно то, что он описал то криптовка тут никаким боком.
    Если нужно просто закодировать массив, то да, можно его закриптовать - сначала сериализуем и потом шифруем ка строку.
    PHP:
    $crypt mcrypt_encrypt (MCRYPT_RIJNDAEL_256$keyserialize($ARRAY), MCRYPT_MODE_ECB$iv);
    2. Если нужно именно то, что сказал автор- то чуть сложнее
    есть ключ, скажем 2314. И перебираем массив меняя местами элементы массива соотв. ключу- первый элемент меняем со вторым, второй (в получившимся массиве) с третьим, третий с первым, 4 с 4 (т.е не меняем)... При раскодировании- в обратном порядке делаем и всё. Ну стоит сказать что ключ обязательно отгда должен быть размером с массив т.е если в массиве 10 элементов, то делаем ключ не 2314 а 2314 2314 23 без пробелов.

    3. Ну можно ещё поизвращатся с функцие пользовательской сортировки- но это намного сложнее
     
  5. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    358
    Симпатии:
    36
    Да, наверно неправильно сформулировал. Действительно сортировка нужна по ключу. Только массив не статичен и элементов 1000~1500, ключ по сути также не статичен, но путем арифметики можно свести к двухзначному.
     
  6. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Скорость очень важна? Вот пример алгоритмы что я говорил. Кормим его ключом и массивом любой длины. Вложенности нет.
    PHP:

    $inputArray  
    = array();
     for (
    $i=0$i<100; ++$i){
        
    $inputArray[] = $i;
        

    $controlArray $inputArray;
    $realRey_strlen =  sizeof($inputArray) ;
     
    $key 'QWERTYU8g8b6%Uvgy12v8v712^%X T   t57123c';
     
    $realRey substrstr_repeat($keyround(  $realRey_strlen strlen($key) ) +1  ), 0$realRey_strlen );
     

    for (
    $i=$i<$realRey_strlen; ++$i ){
        
    // перестановка
     
        
    $dlinaSdviga $realRey$i];
        if(!
    is_numeric($dlinaSdviga)){
            
    $dlinaSdviga ord($dlinaSdviga)-32;//72
        
    }
        
    // определяем элемент, с которым надо поменять  
        
    $flipId $i+$dlinaSdviga;
        while(
    $flipId >= $realRey_strlen){
            
    $flipId -=  $realRey_strlen;
        }
        if(!isset(
    $inputArray[$flipId ])){
            
    var_dump("EBAAAA"$dlinaSdviga$i$flipId);
            exit;
        }
        list(
    $inputArray[$flipId ], $inputArray[$i ]) = array($inputArray[$i], $inputArray[$flipId]);
        
    }
     
    print_r($inputArray);
    for (
    $i=$realRey_strlen-$i>=0; --$i ){
        
    // перестановка
        
        
    $dlinaSdviga $realRey$i];
        if(!
    is_numeric($dlinaSdviga)){
            
    $dlinaSdviga ord($dlinaSdviga)-32;//72
        
    }
        
    // определяем элемент, с которым надо поменять  
        
    $flipId $i+$dlinaSdviga;
        while(
    $flipId >= $realRey_strlen){
            
    $flipId -=  $realRey_strlen;
        }
        if(!isset(
    $inputArray[$flipId ])){
            
    var_dump($dlinaSdviga$i$flipId);
            exit;
        }
        list(
    $inputArray[$flipId ], $inputArray[$i ]) = array($inputArray[$i], $inputArray[$flipId]);
        
    }

      
    print_r($inputArray);
     if(
    $controlArray === $inputArray){
        echo 
    "Yes! Normal crypted!";
     }else{
        echo 
    "Error!";
     }
     
  7. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    358
    Симпатии:
    36
    Спасибо за цчастие, денвер с скриптом не справился, огромная нагрузка на процессор и память =(
     
  8. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Сейчас времени нет, у меня на 10к всё нормально за 0.4с обработал. но скрипт можно оптимизировать
    substr( str_repeat($key, round( $realRey_strlen / strlen($key) ) +1 ), 0, $realRey_strlen )
    не надо удлинять до всего размера массива. Просто посчитать какой элемент будет последним для разкодирования
    и соответственно
    if(!is_numeric($dlinaSdviga)){
    $dlinaSdviga = ord($dlinaSdviga)-32;//72
    }
    высчитать 1 раз и поместить в массив

    можно уменьшить число проходом по массиву для этого ++$i заменяем на чтото вроде $i += $realRey[1]
    а при разкодировании на $i -= $realRey[1]
     
  9. Levitt

    Levitt

    Регистр.:
    20 май 2008
    Сообщения:
    358
    Симпатии:
    36

    Решение которое полностью удовлетворяет мои запросы:
    PHP:
    function sort_array_func_helper($prev,$count)
    {
        
    $next = ($prev 25173 13849) % $count;
        return (int)
    $next;
    }
    function 
    sort_array_func($arr$key$count)
    {
        
    $results=array();
        
    $cnt=count($arr);
        if (
    $cnt<$count)
        {
            return 
    false;
        }
        
    $indexes=range(0,$cnt-1);
        
    $key=$key $cnt;
     
        for (
    $i=0;$i<$count;$i++)
        {
            
    $idx=sort_array_func_helper($key,$cnt--);
            
    $results[]=$arr[$indexes[$idx]];
            if (!
    $cnt)
            {
                break;
            }
            
    array_splice($indexes,$idx,1);
            
    $indexes=array_values($indexes);
            
    $key=$idx;
           
        }
        return 
    $results;
    }
     
    ####ВЫЗОВ
    $res=sort_array_func($какойто_массив,strlen($_SERVER['REQUEST_URI']),70);
        for (
    $i=0;$i<70;$i++)
            echo 
    $res[$i]."<br>";}