PHP генератор случайных строк - PullRequest
746 голосов
/ 05 декабря 2010

Я пытаюсь создать рандомизированную строку в PHP, и я не получаю абсолютно ничего с этим:

<?php
function RandomString()
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randstring = '';
    for ($i = 0; $i < 10; $i++) {
        $randstring = $characters[rand(0, strlen($characters))];
    }
    return $randstring;
}
RandomString();
echo $randstring;

Что я делаю не так?

Ответы [ 53 ]

1291 голосов
/ 05 декабря 2010

Чтобы ответить на этот вопрос конкретно, две проблемы:

  1. $randstring находится вне области действия, когда вы его повторяете.
  2. Символы не объединяются вместе в цикле.

Вот фрагмент кода с исправлениями:

function generateRandomString($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

Вывести случайную строку с помощью вызова ниже:

// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();

Обратите внимание, что это генерирует предсказуемые случайные строки. Если вы хотите создать безопасные токены, посмотрите этот ответ .

354 голосов
/ 04 ноября 2012

Примечание: str_shuffle() внутренне использует rand(), что не подходит для целей криптографии (например, генерация случайных паролей). Вам нужен безопасный генератор случайных чисел . Это также не позволяет персонажам повторяться.

Еще один способ.

ОБНОВЛЕНО (теперь генерируется любая длина строки):

function generateRandomString($length = 10) {
    return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}

echo  generateRandomString();  // OR: generateRandomString(24)

Вот и все. :)

293 голосов
/ 29 июня 2015

Существует множество ответов на этот вопрос, но ни один из них не использует Криптографически безопасный генератор псевдослучайных чисел (CSPRNG).

Простой, безопасный и правильный ответ - использовать RandomLib и не изобретать велосипед.

Для тех из вас, кто настаивает на изобретении собственного решения, PHP 7.0.0 предоставит random_int() для этой цели; если вы все еще используете PHP 5.x, мы написали PHP 5 polyfill для random_int(), чтобы вы могли использовать новый API даже до обновления до PHP 7.

Безопасное создание случайных целых чисел в PHP не является тривиальной задачей. Вы должны всегда проверять у своих постоянных экспертов по криптографии StackExchange , прежде чем развертывать собственный алгоритм на производстве.

С установленным безопасным целочисленным генератором генерация случайной строки с CSPRNG - прогулка в парке.

Создание безопасной случайной строки

/**
 * Generate a random string, using a cryptographically secure 
 * pseudorandom number generator (random_int)
 * 
 * For PHP 7, random_int is a PHP core function
 * For PHP 5.x, depends on https://github.com/paragonie/random_compat
 * 
 * @param int $length      How many characters do we want?
 * @param string $keyspace A string of all possible characters
 *                         to select from
 * @return string
 */
function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    $pieces = [];
    $max = mb_strlen($keyspace, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $pieces []= $keyspace[random_int(0, $max)];
    }
    return implode('', $pieces);
}

Использование

$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');

Демонстрация : https://3v4l.org/b4PST (Игнорировать сбои PHP 5; требуется random_compat)

132 голосов
/ 04 сентября 2014

Создает строку hexdec длиной 20 символов:

$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars

В PHP 7 ( random_bytes () ):

$string = base64_encode(random_bytes(10)); // ~14 chars, includes /=+
// or
$string = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes(32))), 0, 32); // 32 chars, without /=+
// or
$string = bin2hex(random_bytes(10)); // 20 chars, only 0-9a-f
84 голосов
/ 10 февраля 2013

@ Тасманиски: ваш ответ сработал для меня. У меня была такая же проблема, и я бы посоветовал ее тем, кто когда-либо ищет один и тот же ответ. Вот это от @tasmaniski:

<?php 
    $random = substr(md5(mt_rand()), 0, 7);
    echo $random;
?>

Вот видео на YouTube, показывающее, как создать случайное число

43 голосов
/ 06 февраля 2013

В зависимости от вашего приложения (я хотел генерировать пароли), вы можете использовать

$string = base64_encode(openssl_random_pseudo_bytes(30));

Будучи base64, они могут содержать = или -, а также запрошенные символы.Вы можете сгенерировать более длинную строку, затем отфильтровать и обрезать ее, чтобы удалить их.

openssl_random_pseudo_bytes кажется рекомендуемым способом генерирования правильного случайного числа в php.Почему rand не использует /dev/random Я не знаю.

25 голосов
/ 20 апреля 2014

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

echo substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))),1,10);

Дляразбить его так, чтобы параметры были понятны

// Character List to Pick from
$chrList = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

// Minimum/Maximum times to repeat character List to seed from
$chrRepeatMin = 1; // Minimum times to repeat the seed string
$chrRepeatMax = 10; // Maximum times to repeat the seed string

// Length of Random String returned
$chrRandomLength = 10;

// The ONE LINE random command with the above variables.
echo substr(str_shuffle(str_repeat($chrList, mt_rand($chrRepeatMin,$chrRepeatMax))),1,$chrRandomLength);

Этот метод работает путем случайного повторения списка символов, затем перемешивает объединенную строку и возвращает указанное количество символов.

Вы можете дополнительнорандомизируйте это, рандомизируя длину возвращаемой строки, заменяя $chrRandomLength на mt_rand(8, 15) (для случайной строки от 8 до 15 символов).

24 голосов
/ 24 сентября 2012

Лучший способ реализовать эту функцию:

function RandomString($length) {
    $keys = array_merge(range(0,9), range('a', 'z'));

    $key = "";
    for($i=0; $i < $length; $i++) {
        $key .= $keys[mt_rand(0, count($keys) - 1)];
    }
    return $key;
}

echo RandomString(20);

mt_rand более случайный в соответствии с this и this в php7.rand функция является псевдонимом mt_rand.

24 голосов
/ 26 декабря 2012
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Тад!

19 голосов
/ 05 декабря 2010

$randstring в области действия функции не совпадает с областью, в которой вы ее вызываете. Вы должны присвоить возвращаемое значение переменной.

$randstring = RandomString();
echo $randstring;

Или просто повторить возвращаемое значение:

echo RandomString();

Кроме того, в вашей функции есть небольшая ошибка. В цикле for необходимо использовать .=, чтобы каждый символ добавлялся к строке. Используя =, вы перезаписываете его каждым новым символом вместо добавления.

$randstring .= $characters[rand(0, strlen($characters))];
...