Генератор случайных строк PHP
Я пытаюсь создать рандомизированную строку в PHP, и я не получаю абсолютно никакого результата с этим:
<?php
function RandomString()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring = $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
Что я делаю не так?
30 answers
Чтобы конкретно ответить на этот вопрос, две проблемы:
-
$randstring
не входит в область действия, когда вы повторяете его. - Символы не объединяются вместе в цикле.
Вот фрагмент кода с исправлениями:
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();
Пожалуйста, обратите внимание, что это генерирует предсказуемые случайные строки. Если вы хотите создать безопасные токены, смотрите Это ответ.
Примечание:
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)
Вот и все. :)
Существует множество ответов на этот вопрос, но ни один из них не использует Криптографически безопасный генератор псевдослучайных чисел (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)
*
* 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)
Создает шестнадцатеричную строку длиной 20 символов:
$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars
В PHP 7 (случайные байты()):
$string = base64_encode(random_bytes(10)); // ~14 chars
// or
$string = bin2hex(random_bytes(10)); // 20 chars
@тасманиски: ваш ответ сработал для меня. У меня была та же проблема, и я бы предложил ее тем, кто когда-либо искал такой же ответ. Вот это от @tasmaniski:
<?php
$random = substr(md5(mt_rand()), 0, 7);
echo $random;
?>
В зависимости от вашего приложения (я хотел сгенерировать пароли), вы можете использовать
$string = base64_encode(openssl_random_pseudo_bytes(30));
Будучи base64, они могут содержать =
или -
, а также запрошенные символы. Вы можете создать более длинную строку, затем отфильтровать и обрезать ее, чтобы удалить их.
openssl_random_pseudo_bytes
кажется, это рекомендуемый способ генерирования правильного случайного числа в php. Почему rand
не использует /dev/random
, я не знаю.
Я знаю, что это может быть немного поздно для игры, но вот простая однострочная строка, которая генерирует истинную случайную строку без какого-либо цикла на уровне скрипта или использования библиотек 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 символов).
Лучший способ реализовать эту функцию:
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
является более случайным в соответствии с этим и этим в php7. rand
функция является псевдонимом mt_rand
.
function generateRandomString($length = 15)
{
return substr(sha1(rand()), 0, $length);
}
Тада!
$randstring
область действия функции не совпадает с областью, в которой вы ее вызываете. Вы должны присвоить возвращаемое значение переменной.
$randstring = RandomString();
echo $randstring;
Или просто напрямую повторяйте возвращаемое значение:
echo RandomString();
Кроме того, в вашей функции у вас есть небольшая ошибка. В цикле for вам нужно использовать .=
, чтобы каждый символ добавлялся к строке. Используя =
, вы перезаписываете его каждым новым символом вместо добавления.
$randstring .= $characters[rand(0, strlen($characters))];
Сначала вы определяете алфавит, который хотите использовать:
$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);
Короткие методы..
Вот несколько кратчайших способов генерации случайной строки
<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15);
echo substr(md5(rand()), 0, 7);
echo str_shuffle(MD5(microtime()));
?>
Я протестировал производительность большинства популярных функций там, время, необходимое для генерации 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 символов.
Ради ответ: строка не была объединена, а перезаписана, и результат функции не был сохранен.
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;
}
Это было взято из источников администратора:
/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
return md5(uniqid(mt_rand(), true));
}
Администратор, инструмент управления базами данных, написанный на PHP.
Один очень быстрый способ - сделать что-то вроде:
substr(md5(rand()),0,10);
Это приведет к созданию случайной строки длиной 10 символов. Конечно, некоторые могут сказать, что это немного сложнее с вычислительной точки зрения, но в настоящее время процессоры оптимизированы для очень быстрого выполнения алгоритмов md5 или sha256. И, конечно, если функция rand()
вернет то же значение, результат будет таким же, с вероятностью 1/32767. Если проблема в безопасности, то просто измените rand()
на mt_rand()
Вспомогательная функция из фреймворка 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);
}
Отредактированная версия функции работает нормально, я обнаружил только одну проблему: вы использовали неправильный символ для включения символов $, поэтому символ ’ иногда является частью генерируемой случайной строки.
Чтобы исправить это, измените:
$characters = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;
Кому:
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
Таким образом, используются только заключенные символы, и символ ’никогда не будет частью генерируемой случайной строки.
Еще одна однострочная строка, которая генерирует случайную строку из 10 символов с буквами и цифрами. Он создаст массив с range
(отрегулируйте второй параметр, чтобы задать размер), зациклит этот массив и назначит случайный символ ascii (диапазон 0-9 или a-z), затем взорвет массив, чтобы получить строку.
$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));
Примечание: работает только в PHP 5.3+
Одна строка.
быстрый для огромных строк с некоторой уникальностью.
function random_string($length){
return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
/**
* @param int $length
* @param string $abc
* @return string
*/
function generateRandomString($length = 10, $abc = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
return substr(str_shuffle($abc), 0, $length);
}
Источник из http://www.xeweb.net/2011/02/11/generate-a-random-string-a-z-0-9-in-php/
Мне понравился последний комментарий, в котором использовался 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;
}
function randomString($length = 5) {
return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
Еще один способ сгенерировать случайную строку в 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);
Существует простой код:
echo implode("",array_map(create_function('$s','return substr($s,mt_rand(0,strlen($s)),1);'),array_fill(0,16,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")));
Есть простое руководство:
- Чтобы изменить длину строки , пожалуйста, измените
16
только на другое значение. - Чтобы выбрать один из разных символов, пожалуйста, измените строку символов.
Есть лучшие альтернативы этому, многие из них уже были опубликованы, поэтому я возвращаю вам только ваши вещи с исправлениями
<?php
function RandomString()
{
global $randstring ;
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring .= $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
?>
<?php
/**
* Creates a random string
*
* @param (int) $length
* Length in characters
* @param (array) $ranges
* (optional) Array of ranges to be used
*
* @return
* Random string
*/
function random_string($length, $ranges = array('0-9', 'a-z', 'A-Z')) {
foreach ($ranges as $r) $s .= implode(range(array_shift($r = explode('-', $r)), $r[1]));
while (strlen($s) < $length) $s .= $s;
return substr(str_shuffle($s), 0, $length);
}
// Examples:
$l = 100;
echo '<b>Default:</b> ' . random_string($l) . '<br />';
echo '<b>Lower Case only:</b> ' . random_string($l, array('a-z')) . '<br />';
echo '<b>HEX only:</b> ' . random_string($l, array('0-9', 'A-F')) . '<br />';
echo '<b>BIN only:</b> ' . random_string($l, array('0-1')) . '<br />';
/* End of file */
function getRandomString($length) {
$salt = array_merge(range('a', 'z'), range(0, 9));
$maxIndex = count($salt) - 1;
$result = '';
for ($i = 0; $i < $length; $i++) {
$index = mt_rand(0, $maxIndex);
$result .= $salt[$index];
}
return $result
}
Вот как я это делаю, чтобы получить настоящий уникальный случайный ключ:
$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;
Вы можете использовать time(), так как это временная метка Unix и всегда уникальна по сравнению с другими случайными, упомянутыми выше. Затем вы можете сгенерировать md5sum этого и взять нужную вам длину из сгенерированной строки MD5. В этом случае я использую 10 символов, и я мог бы использовать более длинную строку, если бы хотел сделать ее более уникальной.
Я надеюсь, что это поможет.
Источник: Функция PHP, генерирующая случайные символы
Эта функция PHP работала для меня:
function cvf_ps_generate_random_code($length=10) {
$string = '';
// You can define your own characters here.
$characters = "23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
Использование:
echo cvf_ps_generate_random_code(5);