Генератор случайных строк 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;
Что я делаю неправильно?
Ответы
Ответ 1
Чтобы ответить на этот вопрос конкретно, две проблемы:
-
$randstring
не находится в области видимости, когда вы его $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();
Обратите внимание, что это генерирует предсказуемые случайные строки. Если вы хотите создать безопасные токены, посмотрите этот ответ.
Ответ 2
Примечание: 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)
Что это.:)
Ответ 3
На этот вопрос есть много ответов, но ни один из них не использует криптографически безопасный генератор псевдослучайных чисел (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)
*
* 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);
}
Usage Использование:
$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');
$c = random_str();
Демонстрация: https://3v4l.org/IMJGF (не обращайте внимания на сбои PHP 5; требуется случайный компас)
Ответ 4
Это создает шестнадцатеричную строку длиной 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
Ответ 5
@tasmaniski: ваш ответ сработал для меня. У меня была такая же проблема, и я бы посоветовал ее тем, кто когда-либо ищет один и тот же ответ. Вот это от @tasmaniski:
<?php
$random = substr(md5(mt_rand()), 0, 7);
echo $random;
?>
Вот видео на YouTube, показывающее, как создать случайное число
Ответ 6
В зависимости от вашего приложения (я хотел создать пароли) вы могли бы использовать
$string = base64_encode(openssl_random_pseudo_bytes(30));
Будучи base64, они могут содержать =
или -
, а также запрошенные символы. Вы можете создать более длинную строку, затем отфильтровать и обрезать ее, чтобы удалить их.
openssl_random_pseudo_bytes
представляется рекомендуемым способом генерации правильного случайного числа в php. Почему rand
не использует /dev/random
Я не знаю.
Ответ 7
Вот простая однострочная строка, которая генерирует истинную случайную строку без зацикливания на уровне скрипта или использования библиотек 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 символов).
Ответ 8
Лучший способ реализовать эту функцию:
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
.
Ответ 9
function generateRandomString($length = 15)
{
return substr(sha1(rand()), 0, $length);
}
Тада!
Ответ 10
$randstring
в области функций не совпадает с областью, в которой вы ее называете. Вы должны присвоить возвращаемое значение переменной.
$randstring = RandomString();
echo $randstring;
Или просто прямое эхо возвращаемое значение:
echo RandomString();
Кроме того, в вашей функции у вас есть небольшая ошибка. В цикле for вы должны использовать .=
, чтобы каждый символ добавлялся к строке. Используя =
, вы заменяете его каждым новым символом вместо добавления.
$randstring .= $characters[rand(0, strlen($characters))];
Ответ 11
Сначала вы определяете алфавит, который хотите использовать:
$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special = '[email protected]#$%^&*(){}[],./?';
$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);
Ответ 12
Короткие методы.
Вот несколько кратчайших методов для генерации случайной строки
<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15);
echo substr(md5(rand()), 0, 7);
echo str_shuffle(MD5(microtime()));
?>
Ответ 13
Я тестировал производительность большинства популярных функций там, время, необходимое для создания 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 символов.
Для ответа: строка не была конкатенацией, а перезаписана, и результат функции не был сохранен.
Ответ 14
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;
}
Ответ 15
Один очень быстрый способ - сделать что-то вроде:
substr(md5(rand()),0,10);
Это сгенерирует случайную строку длиной 10 символов. Конечно, некоторые могут сказать, что это немного тяжелее для вычислений, но в настоящее время процессоры оптимизированы для очень быстрого запуска алгоритмов md5 или sha256. И, конечно же, если функция rand()
возвращает то же значение, результат будет таким же, с вероятностью 1/32767 того же самого. Если проблема в безопасности, просто измените rand()
на mt_rand()
Ответ 16
Это было взято из источников администратора:
/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
return md5(uniqid(mt_rand(), true));
}
Adminer, инструмент управления базами данных, написанный на PHP.
Ответ 17
Вспомогательная функция из структуры 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);
}
Ответ 18
/**
* @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-az-0-9-in-php/
Ответ 19
Отредактированная версия функции работает нормально, но есть только одна проблема, которую я обнаружил: вы использовали неправильный символ для вложения $ символов, поэтому этот символ иногда является частью генерируемой случайной строки.
Чтобы это исправить, измените:
$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;
чтобы:
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
Таким образом, используются только вложенные символы, и символ никогда не будет частью генерируемой случайной строки.
Ответ 20
Еще один однострочник, который генерирует случайную строку из 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 и позже
Ответ 21
Один лайнер.
Это быстро для огромных струн с некоторой уникальностью.
function random_string($length){
return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
Ответ 22
Мне понравился последний комментарий, который использовал 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;
}
Ответ 23
function randomString($length = 5) {
return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
Ответ 24
Другой способ генерации случайной строки в 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);
Ответ 25
Есть простой код:
echo implode("",array_map(create_function('$s','return substr($s,mt_rand(0,strlen($s)),1);'),array_fill(0,16,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")));
Есть простое руководство:
- Чтобы изменить длину строки, измените
16
на другое значение. - Чтобы выбрать из разных символов, пожалуйста, измените строку символов.
Ответ 26
Наконец, я нашел решение, чтобы получить случайные и уникальные значения.
Мое решение:
substr(md5(time()), 0, 12)
time
всегда возвращает метку времени, и оно всегда уникально. Вы можете использовать его с MD5, чтобы сделать его лучше.
Ответ 27
Параметрированный однострочный шрифт с использованием только родных функций 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))))))
Ответ 28
Есть лучшие альтернативы этому. Многие уже были опубликованы, поэтому я возвращаю вам только ваши исправления:
<?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
function RandomString()
{
global $randstring;
$characters = str_split('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
array_filter ($characters,function($var)use($characters,&$randstring){
$randstring .= $characters[rand(0, count($characters)-1)];
});
return $randstring;
}
RandomString();
echo $randstring.'<hr>';
//.. OR ..
$randstring = '';
echo(RandomString());
?>
Или другой:
<?php
function s($length){
for($i=0;
($i<$length) and
(
($what=rand(1,3))
and
(
(
($what==1) and
($t=rand(48, 57)
)
) or
(
($what==2) and
($t=rand(65, 90))
) or
(
($what==3) and
($t=rand(97, 122)
)
)
) and
(print chr($t))
);
$i++)
;
}
s(10);
?>
Ответ 29
Вот как я делаю это, чтобы получить настоящий уникальный случайный ключ:
$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;
Вы можете использовать time(), поскольку это временная метка Unix и всегда уникальна по сравнению с другими случайными значениями, упомянутыми выше. Затем вы можете создать md5sum и взять нужную длину из сгенерированной строки MD5. В этом случае я использую 10 символов, и я мог бы использовать более длинную строку, если бы захотел сделать ее более уникальной.
Надеюсь, это поможет.
Ответ 30
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
}