Как создать случайную строку с помощью PHP? - PullRequest
56 голосов
/ 12 мая 2009

Я знаю, что функция rand в PHP генерирует случайные целые числа, но как лучше всего создать случайную строку, такую ​​как:

Оригинальная строка, 9 символов

$string = 'abcdefghi';

Пример случайного ограничения строки до 6 символов

$string = 'ibfeca';

ОБНОВЛЕНИЕ: Я нашел тонны этих типов функций, в основном я пытаюсь понять логику каждого шага.

ОБНОВЛЕНИЕ: функция должна генерировать любое количество символов по мере необходимости.

Пожалуйста, прокомментируйте детали, если ответите.

Ответы [ 19 ]

2 голосов
/ 30 марта 2013

Большинство аспектов этого уже обсуждалось, но я бы порекомендовал небольшое обновление: Если вы используете это для розничного использования, я бы избегал домен ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

и вместо этого используйте: ABCDEFGHJKMNPQRSTUVWXY3456789

Конечно, вы получите гораздо меньше символов, но это сэкономит массу хлопот, поскольку клиенты не могут принять 0 за O, или 1 за l или 2 за Z. Также вы можете сделать UPPER на входе клиенты могут затем вводить буквы в верхнем или нижнем регистре - это также иногда сбивает с толку, поскольку они могут выглядеть одинаково.

1 голос
/ 18 января 2013
// @author http://codeascraft.etsy.com/2012/07/19/better-random-numbers-in-php-using-devurandom/                                                
function devurandom_rand($min = 0, $max = 0x7FFFFFFF)
{
    $diff = $max - $min;
    if ($diff < 0 || $diff > 0x7FFFFFFF) {
        throw new RuntimeException('Bad range');
    }
    $bytes = mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
    if ($bytes === false || strlen($bytes) != 4) {
        throw new RuntimeException('Unable to get 4 bytes');
    }
    $ary = unpack('Nint', $bytes);
    $val = $ary['int'] & 0x7FFFFFFF; // 32-bit safe                           
    $fp = (float) $val / 2147483647.0; // convert to [0,1]                          
    return round($fp * $diff) + $min;
}

function build_token($length = 60, $characters_map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
    $map_length = mb_strlen($characters_map)-1;
    $token = '';
    while ($length--) {
        $token .= mb_substr($characters_map, devurandom_rand(0,$map_length),1);
    }
    return $token;
}

Это будет работать только в среде UNIX, где PHP скомпилирован с mcrypt.

0 голосов
/ 10 марта 2019

Это старый вопрос, но я хочу попробовать опубликовать свое решение ... Я всегда использую эту функцию для генерации произвольной случайной буквенно-цифровой строки ...

<?php
  function random_alphanumeric($length) {
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345689';
    $my_string = '';
    for ($i = 0; $i < $length; $i++) {
      $pos = mt_rand(0, strlen($chars) -1);
      $my_string .= substr($chars, $pos, 1);
    }
    return $my_string;
  }
  $test = random_alphanumeric(50); // 50 characters
  echo $test;
?>

test: UFOruSSTCPIqxTRIIMTRkqjOGidcVlhYaS9gtwttxglheVugFM

если вам нужны две или более уникальных строки, вы можете использовать этот трюк ...

$string_1 = random_alphanumeric(50);
$string_2 = random_alphanumeric(50);
while ($string_1 == $string_2) {
  $string_1 = random_alphanumeric(50);
  $string_2 = random_alphanumeric(50);
  if ($string_1 != $string_2) {
     break;
  }
}
echo $string_1;
echo "<br>\n";
echo $string_2;

$ string_1: tMYicqLCHEvENwYbMUUVGTfkROxKIekEB2YXx5FHyVByp3mlJO

$ string_2: XdMNJYpMlFRKFDlF6GhVn6jsBVNQ1BCCevj8yK2niFOgpDI2MU

Надеюсь, это поможет.

0 голосов
/ 21 мая 2019
echo substr(bin2hex(random_bytes(14)), 0, $length);
0 голосов
/ 12 мая 2009

вы можете создать массив символов, а затем использовать rand (), чтобы выбрать букву из массива и добавить ее в строку.

$letters = array( [0] => 'a' [1] => 'b' [2] => 'c' [3] => 'd' ... [25] = 'z');

$lengthOfString = 10;
$str = '';

while( $lengthOfString-- )
{
   $str .= $letters[rand(0,25)];
}
echo $str;

* обратите внимание, что это позволяет повторять символы

0 голосов
/ 27 апреля 2012

Это основано на решении Gumbo , добавляя функциональность в список набора символов, которые будут пропущены в базовом наборе символов. Случайная строка выбирает символы из $base_charset, которые также не отображаются в $skip_charset.

/* Make a random string of length using characters from $charset, excluding $skip_chars.
 * @param length (integer) length of return value
 * @param skip_chars (string) characters to be excluded from $charset
 * @param charset (string) characters of posibilities for characters in return val
 * @return (string) random string of length $length    */
function rand_string(
        $length, 
        $skip_charset = '', 
        $base_charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'){
  $skip_len = strlen($skip_charset);
  for ($i = 0; $i<$skip_len; $i++){
    $base_charset = str_replace($skip_charset[$i], '', $base_charset);
  }
  cvar_dump($base_charset, '$base_charset after replace');
  $str = '';
  $count = strlen($base_charset);
  while ($length--) {
    $str .= $base_charset[mt_rand(0, $count - 1)];
  }
  return $str;
}

Вот несколько примеров использования. В первых двух примерах используется значение по умолчанию для $base_charset. Последний пример явно определяет $base_charset.

echo rand_string(15, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
//  470620078953298
echo rand_string(8, 'abcdefghijklmnopqrstuvwxyz0123456789');
//  UKLIHOTFSUZMFPU
echo rand_string(15, 'def', 'abcdef');
//  cbcbbccbabccaba
0 голосов
/ 04 февраля 2015

Если вас не беспокоит время, память или эффективность процессора, и если ваша система может справиться с этим, почему бы не попробовать этот алгоритм?!

function randStr($len, $charset = 'abcdABCD0123') {
    $out = '';
    $str = array();

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        $str[$i] = $charset;

        shuffle($str);
        $charset .= implode($charset, $str);
        $charset = str_shuffle($charset);
    }

    $str = array_flip($str);
    $str = array_keys($str);

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        shuffle($str);
    }

    $str = implode('', $str);

    for ($i = 0; $i < strlen($str); $i++) {
        $index = mt_rand(1, strlen($str));
        $out .= $str[$index - 1];
    }

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        $out = str_shuffle($out);
    }

    return substr($out, 0, $len);
}

Возможно, это будет читаться лучше, если он использует рекурсию, но я не уверен, использует ли PHP хвостовую рекурсию или нет ...

0 голосов
/ 12 мая 2009

Хотите создать свой пароль путем случайной перестановки исходных букв? Должно ли оно содержать уникальные символы?

Используйте rand для выбора случайных букв по индексу.

0 голосов
/ 05 февраля 2013

ну, я искал решение, и я вроде как использовал решение @Chad Birch, объединенное с решением @ Gumbo. Вот что я придумал:

function get_random_string($length, $valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456790!·$%&/()=?¿¡',.-;:+*`+´ç")
{
    $random_string = "";
    $num_valid_chars = strlen($valid_chars);
    for ($i = 0; $i < $length; $i++, $random_string .= $valid_chars[mt_rand(1, $num_valid_chars)-1]);
    return $random_string;
}

Я думаю, что комментарии в значительной степени излишни, так как ответы, которые я использовал для создания этого, уже тщательно прокомментированы. Ура! * * 1004

...