PHP генератор случайных строк

815

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

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

    RandomString();
    echo $randstring;

Что я делаю неправильно?

Капитан Молния
источник
241
Мое однострочное решение для генерации короткой строки - substr (md5 (rand ()), 0, 7); удачи ...
Тасманиски
5
@tasmaniski .. Ваше решение в порядке .. Но оно менее рандомизировано! В вашем примере количество генерируемых случайных строк ограничено размером целого числа. (2 ^ 32) в максимуме. В случае другого решения вы можете сгенерировать (62 ^ 8) .. В случае, если я хочу строки большего размера, тогда число отдельных строк остается в максимуме 2 ^ 32, но в другое решение это увеличивается до (62 ^ n) ..
Ману
9
Вы забыли добавить каждый новый сгенерированный символ в строку. Вы просто перезаписываете все как есть. Должно быть $ randstring. = $ Символов ..
Спок
3
@CaptainLightning Можете ли вы заменить принятый ответ на один из наиболее безопасных? :)
Скотт Аркишевский
2
strlen($characters)=> strlen($characters) - 1- длина строки начинается с 1
Zippp

Ответы:

1395

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

  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();

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

Стивен Уоткинс
источник
34
@FranciscoPresencia, лучше "тратить" лишнюю переменную, так как вызывается метод в условии сравнения цикла.
Рико Соннтаг
200
Вся эта работа, почему не просто что-то вроде substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH
4
Спасибо за код, но, пожалуйста, измените rand()на mt_rand(). Я использовал ваш метод и столкнулся с кучей имен.
Нейт
5
@FranciscoPresencia Вы знаете, насколько это ужасно неэффективно? Вы проверяете длину строки дважды за итерацию! Strlen внутри цикла также должен кэшироваться в переменной перед входом в цикл.
developerbmw
4
Это не хорошее решение. Сгенерированные строки будут предсказуемы. :(
Скотт Аркишевский
370

Примечание: 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)

Вот и все. :)

А. Чеширов
источник
64
+1 за самый короткий ответ :). Но не лучший ответ для каждого варианта использования. Этот код будет выводить строки, в которых каждый символ не будет появляться более одного раза (что делает его более слабым при атаках методом грубой силы), и не будет выводить ничего более 62 символов.
Дэвид
17
Не делай этого, он крайне слабый. Чем дольше вы делаете свою случайную строку, тем слабее она будет.
Абхи Беккерт
23
Это может быть слабым, но это быстро и легко. В зависимости от варианта использования это нормально - я использовал его, потому что мне не требовались безопасность или сила; просто быстрая перестановка. Я пишу юнит-тест, и это дает мне подходящую случайную информацию для тестирования.
SDC
23
@FranciscoPresencia причина, по которой он не защищен, потому что он никогда не использует один и тот же символ дважды. Это делает его ужасным генератором паролей. Пожалуйста, все перестанут голосовать, это совершенно небезопасно, никогда не должно использоваться. По мере того, как пароль увеличивается, количество символов, которые вы должны проверить в грубой силе, становится короче, потому что вы не беспокоитесь о проверке ранее использованного символа.
Абхи Беккерт
8
@FranciscoPresencia: Я поддерживаю ваши комментарии об избежании использования этого для случайных паролей. Однако я не согласен с тем, что этот ответ не должен быть плюсовым. У меня есть опция plus-one'd, потому что это эффективное однострочное решение для генерации случайных строк (оригинальная тема этого вопроса).
Брайт
331

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

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

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

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

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

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

/**
 * Generate a random string, using a cryptographically secure 
 * pseudorandom number generator (random_int)
 *
 * This function uses type hints now (PHP 7+ only), but it was originally
 * written for PHP 5 as well.
 * 
 * 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(
    int $length = 64,
    string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
): string {
    if ($length < 1) {
        throw new \RangeException("Length must be a positive integer");
    }
    $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');
$c = random_str();

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

Скотт Аркишевский
источник
3
В начале функции добавьте $keyspace = str_shuffle($keyspace );для большей безопасности
Евгений Дмитриев
13
Что вы подразумеваете под «для большей безопасности»? Мы уже используем безопасный генератор случайных чисел.
Скотт
5
@JGEstiot Создание надежно случайных строк требует криптографически безопасной случайности. Кто-то, ищущий «как генерировать случайные строки в PHP», лучше получает защищенный ответ, чем небезопасный ответ.
Скотт Аркишевский
1
@ Scott Arciszewski Вам не нужно создавать криптографически случайные строки каждый раз, когда вы создаете случайные строки. Речь шла о создании рандомизированных строк, и это не имеет ничего общего с безопасностью. Вы предполагали, что строка будет использоваться в контексте, чувствительном к безопасности, и добавляете уровень сложности, который отвлекает от сути вопроса.
Э.Г. Эстиот
45
Использование random_int()вместо rand()или не mt_rand()добавляет сложности для разработчика. В то же время это дает им большую безопасность. Люди, которые приходят в StackOverflow в поисках быстрых решений, могут не знать, должна ли вещь, которую они строят, быть безопасной или нет. Если мы дадим им ответы по умолчанию, они создадут более безопасный Интернет, даже если, с их точки зрения, это совершенно случайно. Почему вы противостоите этой цели, для меня загадка.
Скотт Аркишевский
156

Это создает шестнадцатеричную строку длиной 20 символов:

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

В PHP 7 ( random_bytes () ):

$string = base64_encode(random_bytes(10)); // ~14 characters, includes /=+
// or
$string = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes(32))), 0, 32); // 32 characters, without /=+
// or
$string = bin2hex(random_bytes(10)); // 20 characters, only 0-9a-f
Rudie
источник
Обратите внимание, что openssl_random_pseudo_bytes()не использовал криптографически сильный алгоритм до php 5.6. Связанная ошибка: bugs.php.net/bug.php?id=70014
acidtv
Также обратите внимание, что наименьшая строка, которую он может сделать, имеет длину 2. Если вы передадите длину в 1 байт или меньше, openssl_random_pseudo_bytes()вы ничего не получите обратно. Кроме того, обратите внимание, что при использовании, bin2hex(openssl_random_pseudo_bytes($length / 2))так как вы работаете с целыми числами, он автоматически удалит модуль и будет использовать следующий наименьший кратный 2. Таким образом, $length = 19получится строка длины 18.
Натан Ф.
Предложение использовать его как содержимое файла, которое может быть открыто через fgets($fp, 1024)любой редактор файлов, у которого есть проблемы с очень длинными строками: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }установите, $splitдолжно nullли оно возвращать одну строку . Таким образом, вы можете использовать его для обоих случаев.
Мгут
Мне действительно нравится решение random_bytes для PHP 7, но если вам нужно, чтобы строка состояла из определенного числа символов, что-то вроде этой работы? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programster
Это, без сомнения, лучшее решение. Занимает очень мало места и очень прост для понимания.
Мэтью Кэмпбелл
92

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

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

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

Humphrey
источник
6
если ваша строка основана только на случайном целом числе, почему бы просто не использовать случайное целое число? они не получают ничего более глубокого, хешируя их ... и сокращая ваш хэш, фактически сводят на нет ту маленькую энтропию, с которой вам пришлось начинать.
Surrican
4
Имейте в виду, md5что результатом будет ограничение в 30 символов и всегда строчные буквы.
фырье
3
Кроме того, rand () не должен использоваться для криптографии. Если вы хотите сгенерировать крипографически надежную строку, используйте openssl_random_pseudo_bytes .
Mattkgross
md5(rand())предлагает только 2 ^ 32 возможных значений. Это означает, что в среднем после 2 ^ 16 случайных строк вы ожидаете, что одна из них повторится.
Скотт Аркишевский
2
Ну, я бы поспорил, что ОП не говорит о "надежно случайных строках". Это компактное, простое и запоминающееся решение для правильных вариантов использования. И, если вам нужно позаботиться о возможных коллизиях, почему бы не добавить / добавить временную метку к случайной строке? :)
Эренор Пас
46

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

$string = base64_encode(openssl_random_pseudo_bytes(30));

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

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

rjmunro
источник
2
rand не использует / dev / urandom, потому что он доступен только в posix-подобных средах и не переносим.
MacroMan
3
@MacroMan Но openssl_random_pseudo_bytes() это портативный.
Ja͢ck
Если вы хотите удалить лишние символы base64, попробуйте это: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley
3
Это не так, но я бы посоветовал с осторожностью избегать нежелательных персонажей. Посмотрите этот запрос на получение доступа к серверу OAuth2 PHP-лиги , например.
Скотт Аркишевский
Это один из лучших ответов. Жаль, что больше нет поддержки. Я бы порекомендовал отредактировать ваш ответ для лучшей обработки нежелательных символов.
Jcuenod
28

Вот простая однострочная строка, которая генерирует истинную случайную строку без зацикливания на уровне сценария или использования библиотек 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 символов).

Краанг Прайм
источник
извините, но когда выбран один персонаж, вероятность его повторения не так высока, как у других персонажей, все еще оставшихся в пуле. здесь нет никакой случайности ...
The Surrican
@TheSurrican - Вы были бы неверны в этом утверждении. Все символы имеют равную вероятность с использованием этого алгоритма, и, таким образом, действительно случайны. Это обеспечивается повторением строки chrList $ chrRepeatMax, и волшебство действительно происходит в str_shuffle, который определяет случайность.
Краанг Прайм
Все символы появляются только один раз, и это очень склонно к
грубым
@venimus Это неправильно. Строка char дублируется для любого количества символов (см. $chrRepeatMaxИ $chrRepeatMin), поэтому строка из 10 символов (маловероятно, но возможно) может быть «aaaaaaaaaa».
Краанг Прайм
@SanuelJackson Извините, я не прокомментировал. Я поставил комментарий на неправильный ответ. Вы правы! Я на самом деле использовал твой "трюк", но не использовал mt_rand, потому что это бесполезно IMHO. Это не добавляет энтропии. Только что использовал const с максимальной длиной.
Venimus
25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Тада!

Давор
источник
Имейте в виду, sha1что результатом будет ограничение в 40 символов и всегда строчные буквы.
фырье
3
Строки sha1 не случайны, некоторые символы встречаются чаще, чем другие. Было бы неразумно использовать это в тех случаях, когда вы действительно хотите случайность, как для паролей.
Кит Сунд
1
@KitSunde - да, sha не случайный, rand () - случайный. И ша прекрасно подходит для того, что здесь нужно. ОП не нуждается в крипто-уровне случайности.
Давор
@Davour rant()быть случайным не имеет значения, когда ша не распределен равномерно. Если вы случайным образом выбираете неравномерное распределение, вы получаете точно такое же неравномерное распределение. Я подчеркиваю не случайность "криптоуровня", если бы это было так, вы не должны использовать rand()также. Требуется минимальное усилие, чтобы извлечь из равномерного распределения, как в принятом ответе, и это так же случайно, как и rand (), что вполне разумно.
Кит Сунд
@KitSunde - это не имеет никакого значения в конце концов. Это именно то определение, как гидроразработка и золотое покрытие.
Давор
24

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

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является более случайным в соответствии с этим и этим в PHP 7. randФункция является псевдонимом mt_rand.

Ратиент Баскаран
источник
1
Внимание: mt_randне генерирует криптографически безопасные значения. Для этого вы должны использовать PHP7 random_intили random_bytes.
июня
18

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

$randstring = RandomString();
echo $randstring;

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

echo RandomString();

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

$randstring .= $characters[rand(0, strlen($characters))];
BoltClock
источник
14

Сначала вы определяете алфавит, который хотите использовать:

$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special  = '~!@#$%^&*(){}[],./?';
$alphabet = $alphanum . $special;

Затем используйте openssl_random_pseudo_bytes()для генерации правильных случайных данных:

$len = 12; // length of password
$random = openssl_random_pseudo_bytes($len);

Наконец, вы используете эти случайные данные для создания пароля. Поскольку каждый символ в $randomможет быть chr(0)до chr(255), код использует остаток после деления своего порядкового значения, $alphabet_lengthчтобы убедиться, что выбираются только символы из алфавита (обратите внимание, что это смещает случайность):

$alphabet_length = strlen($alphabet);
$password = '';
for ($i = 0; $i < $len; ++$i) {
    $password .= $alphabet[ord($random[$i]) % $alphabet_length];
}

В качестве альтернативы и, как правило, лучше использовать RandomLib и SecurityLib :

use SecurityLib\Strength;

$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new Strength(Strength::MEDIUM));

$password = $generator->generateString(12, $alphabet);
оборота Яцк
источник
Использование оператора по модулю %приведет к смещенному выводу. Тем не менее, сильный +1 для RandomLib. Не изобретай велосипед.
Скотт Аркишевский
1
Да, новая функция random_int () хороша: D
Ja͢ck
11

Короткие Методы ..

Вот кратчайший способ генерации случайной строки

<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15); 

echo substr(md5(rand()), 0, 7);

echo str_shuffle(MD5(microtime()));
?>
Пунит Гаджар
источник
10

Там я проверил производительность большинства популярных функций, время, необходимое для генерации 1 000 000 строк из 32 символов на моем блоке:

2.5 $s = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,32);
1.9 $s = base64_encode(openssl_random_pseudo_bytes(24));
1.68 $s = bin2hex(openssl_random_pseudo_bytes(16));
0.63 $s = base64_encode(random_bytes(24));
0.62 $s = bin2hex(random_bytes(16));
0.37 $s = substr(md5(rand()), 0, 32);
0.37 $s = substr(md5(mt_rand()), 0, 32);

Обратите внимание, что не важно, как долго это было на самом деле, но что медленнее и какое быстрее, так что вы можете выбирать в соответствии с вашими требованиями, включая готовность к криптографии и т. Д.

substr () вокруг MD5 был добавлен ради точности, если вам нужна строка длиной не более 32 символов.

Ради ответа: строка не была конкатенирована, но перезаписана и результат функции не был сохранен.

Putnik
источник
Я думаю, что лучший ответ. Спасибо!
NSukonny
10

PHP 7+ Создание криптографически безопасных случайных байтов с помощью функции random_bytes .

$bytes = random_bytes(16);
echo bin2hex($bytes);

Возможный вывод

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ Генерация псевдослучайных байтов с помощью функции openssl_random_pseudo_bytes .

$bytes = openssl_random_pseudo_bytes(16);
echo bin2hex($bytes);

Возможный вывод

e2d1254506fbb6cd842cd640333214ad


Лучший вариант использования может быть

function getRandomBytes($length = 16)
{
    if (function_exists('random_bytes')) {
        $bytes = random_bytes($length / 2);
    } else {
        $bytes = openssl_random_pseudo_bytes($length / 2);
    }
    return bin2hex($bytes);
}
echo getRandomBytes();

Возможный вывод

ba8cc342bdf91143

Мадан Сапкота
источник
Это не будет генерировать строку с заданной длиной
Тимберман
@Timberman сейчас сгенерирует точную длину.
Мадан Сапкота
9

Один очень быстрый способ - сделать что-то вроде:

substr(md5(rand()),0,10);

Это сгенерирует случайную строку длиной 10 символов. Конечно, некоторые могут сказать, что это немного сложнее в вычислительной сфере, но в настоящее время процессоры оптимизированы для очень быстрого запуска алгоритмов md5 или sha256. И, конечно, если rand()функция возвращает одно и то же значение, результат будет таким же, с вероятностью 1/32767 того же самого. Если проблема в безопасности, просто измените rand()наmt_rand()

Акатоша
источник
7
function rndStr($len = 64) {
     $randomData = file_get_contents('/dev/urandom', false, null, 0, $len) . uniqid(mt_rand(), true);
     $str = substr(str_replace(array('/','=','+'),'', base64_encode($randomData)),0,$len);
    return $str;
}
Руслан Ибрагимов
источник
4
Это не портативно; если вы попытаетесь запустить это в любой не-posix среде, это приведет к фатальной ошибке.
Брайан Эйджи
6

Вспомогательная функция из рамок Laravel 5

/**
 * Generate a "random" alpha-numeric string.
 *
 * Should not be considered sufficient for cryptography, etc.
 *
 * @param  int  $length
 * @return string
 */
function str_random($length = 16)
{
    $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}
artnikpro
источник
4
«Не должно считаться достаточным для криптографии и т. Д.» Это должно быть сильно подчеркнуто.
Скотт Аркишевский
4

Отредактированная версия функции работает нормально, но есть только одна проблема, которую я обнаружил: вы использовали неправильный символ для вложения $ символов, поэтому символ 'иногда является частью генерируемой случайной строки.

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

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

чтобы:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

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

bmcswee
источник
4

Еще один однострочник, который генерирует случайную строку из 10 символов с буквами и цифрами. Он создаст массив с range(отрегулируйте второй параметр, чтобы установить размер), зацикливается на этом массиве и назначает случайный символ ASCII (диапазон 0-9 или az), затем внедряет массив, чтобы получить строку.

$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));

Примечание: это работает только в PHP 5.3 и позже

Казимир
источник
наконец, действительно случайное решение, а не какой-то раздутый хэш 32-битного случайного целого числа или перемешанной строки ...
The Surrican
есть только одна проблема: числа могут встречаться в виде символов, что не так случайно, как хотелось бы. +1 для лучшего решения на этой странице. настроить это и его идеально.
Surrican
настроить ... как это? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth
4

Один лайнер.

Это быстро для огромных струн с некоторой уникальностью.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
Джейкоб Смит
источник
md5(rand())это ужасно небезопасный способ генерирования случайного числа.
Скотт Аркишевский
1
Строка с длиной X и некоторой уникальностью является намерением. Истинная случайность не является целью.
Джейкоб Смит
4

Вот мое простое однострочное решение для генерации удобного случайного пароля, за исключением символов, которые похожи друг на друга, таких как «1» и «l», «O» и «0» и т. Д., Здесь 5 символов, но вы можете легко измените это конечно:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);
rAthus
источник
Это идеально для создания случайных строк идентификаторов для последующего вызова в jquery. ИДК, если это хорошая практика, но это мне очень помогло, не используя такой ответ, как принятый ...
Родриго
3

Мне понравился последний комментарий, в котором использовался openssl_random_pseudo_bytes, но для меня это не было решением, так как мне все равно пришлось удалить ненужные символы, и я не смог получить строку заданной длины. Вот мое решение ...

function rndStr($len = 20) {
    $rnd='';
    for($i=0;$i<$len;$i++) {
        do {
            $byte = openssl_random_pseudo_bytes(1);
            $asc = chr(base_convert(substr(bin2hex($byte),0,2),16,10));
        } while(!ctype_alnum($asc));
        $rnd .= $asc;
    }
    return $rnd;
}
RKaneKnight
источник
3
function randomString($length = 5) {
    return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
Анжит К.П.
источник
3

Вот еще одно решение.

function genRandomString($length = 10)
{
    if($length < 1)
        $length = 1;
    return substr(preg_replace("/[^A-Za-z0-9]/", '', base64_encode(openssl_random_pseudo_bytes($length * 2))), 0, $length);
}

PS. Я использую PHP 7.2 на Ubuntu.

Умайр Хан
источник
2

Другой способ генерирования случайной строки в PHP :

function RandomString($length) {
    $original_string = array_merge(range(0,9), range('a','z'), range('A', 'Z'));
    $original_string = implode("", $original_string);
    return substr(str_shuffle($original_string), 0, $length);
}
echo RandomString(6);
Ахилрай Н.С.
источник
2

Вот как я делаю это, чтобы получить действительно уникальный случайный ключ:

$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;

Вы можете использовать time (), так как это временная метка Unix и всегда уникальна по сравнению с другими случайными числами, упомянутыми выше. Затем вы можете сгенерировать сумму md5 и взять необходимую длину из сгенерированной строки MD5 . В этом случае я использую 10 символов, и я мог бы использовать более длинную строку, если я хотел бы сделать ее более уникальной.

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

шерпа
источник
2
Конечно, time()он далеко не уникален: он будет возвращать одно и то же значение снова и снова, пока не закончится текущая секунда. Что действительно обеспечивает некоторую случайность, так это то, что str_shuffle()остальная часть кода только уменьшает выборку, из которой выбираются символы.
Альваро Гонсалес
1
поэтому то, что вы в основном делаете, это перемешивает 32-битное целое число. здесь не так много энтропии ...
The Surrican
2
Злоумышленник может угадать значение, возвращаемое time()(это только временная метка), это слабый источник случайности.
AL
2

Параметризованный однострочник, использующий только нативные функции PHP , работающий с PHP 5.1.0

str_shuffle(implode('', (array_intersect_key(($map =  array_map('chr', array_merge(array_map('mt_rand', array_fill(0, $length = 25, 48), array_fill(0,$length,57)),array_map('mt_rand', array_fill(0, $length, 65), array_fill(0,$length,90)),array_map('mt_rand', array_fill(0, $length, 97), array_fill(0,$length,122))))), array_flip($keys = array_rand($map, $length))))))
user10099
источник