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

736

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

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

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

  • 207
    Мое однострочное решение для генерации короткой строки - substr (md5 (rand ()), 0, 7); удачи ...
  • 4
    @tasmaniski .. Ваше решение в порядке .. Но оно менее рандомизировано! В вашем примере количество случайных строк, которые могут быть сгенерированы, ограничено размером целого числа. (2 ^ 32) в максимуме. В случае другого решения вы можете сгенерировать (62 ^ 8) .. В случае, если я хочу строки большего размера, тогда число различных строк остается в максимуме 2 ^ 32, но в другое решение увеличивается до (62 ^ n) ..
Показать ещё 9 комментариев
Теги:
string
random

50 ответов

1292
Лучший ответ

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

  1. $randstring не находится в области видимости, когда вы его $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();

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

  • 0
    Ваше обновление странное, это случайное поколение, но ни один символ не может быть использован более одного раза.
  • 2
    Зачем тратить эту дополнительную переменную, $i ? Просто сделайте for ($randomString = ''; strlen($STR) < 50;) $randomString .= $characters[rand(0, strlen($characters) - 1)]; вместо вашего цикла, или упрощенно, for ($STR = ''; strlen($STR) < 50;) $STR .= $CHR[rand(0, strlen($CHR) - 1)];
Показать ещё 13 комментариев
321

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

Что это.:)

  • 63
    +1 за самый короткий ответ :). Но не лучший ответ для каждого варианта использования. Этот код будет выводить строки, в которых каждый символ не будет появляться более одного раза (что делает его более слабым при атаках методом грубой силы), и не будет выводить ничего более 62 символов.
  • 16
    Не делай этого, он крайне слабый. Чем дольше вы делаете свою случайную строку, тем слабее она будет.
Показать ещё 14 комментариев
255

На этот вопрос много ответов, но никто из них не использует криптографически безопасный генератор псевдослучайных чисел (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)

  • 3
    В начале функции добавьте $keyspace = str_shuffle($keyspace ); для большей безопасности
  • 11
    Что вы подразумеваете под «для большей безопасности»? Мы уже используем безопасный генератор случайных чисел.
Показать ещё 8 комментариев
119

Создает строку 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
  • 0
    Обратите внимание, что openssl_random_pseudo_bytes() не использовал криптографически сильный алгоритм до php 5.6. Связанная ошибка: bugs.php.net/bug.php?id=70014
  • 0
    Также обратите внимание, что наименьшая строка, которую он может сделать, имеет длину 2. Если вы передадите байту длиной 1 или меньше в openssl_random_pseudo_bytes() вы ничего не получите обратно. Также обратите внимание, что при использовании bin2hex(openssl_random_pseudo_bytes($length / 2)) так как вы работаете с целыми числами, он автоматически удалит модуль и будет использовать следующий наименьший кратный 2. Таким образом, $length = 19 создаст строку длина 18.
Показать ещё 6 комментариев
80

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

<?php 
    $random = substr(md5(mt_rand()), 0, 7);
    echo $random;
?>
  • 5
    если ваша строка основана только на случайном целом числе, почему бы просто не использовать случайное целое число? они не получают ничего более глубокого, хешируя их ... и сокращая ваш хэш, фактически сводят на нет ту маленькую энтропию, с которой вам пришлось начинать.
  • 4
    Имейте в виду, md5 приведет к ограничению в 30 символов и всегда строчных символов.
Показать ещё 4 комментария
43

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

$string = base64_encode(openssl_random_pseudo_bytes(30));

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

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

  • 1
    rand не использует / dev / urandom, потому что он доступен только в posix-подобных средах и не переносим.
  • 3
    @MacroMan Но openssl_random_pseudo_bytes() является переносимым.
Показать ещё 3 комментария
24

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

  • 0
    извините, но когда выбран один персонаж, вероятность его повторения не так высока, как у других персонажей, все еще находящихся в пуле. здесь нет никакой случайности ...
  • 0
    @TheSurrican - Вы были бы неверны в этом утверждении. Все символы имеют одинаковую вероятность, используя этот алгоритм, и, следовательно, действительно случайны. Это обеспечивается повторением строки chrList $ chrRepeatMax, и волшебство действительно происходит в str_shuffle, который определяет случайность.
Показать ещё 5 комментариев
24
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Тада!

  • 0
    Имейте в виду, что sha1 приведет к ограничению в 40 символов и всегда строчных символов.
  • 3
    Строки sha1 не случайны, некоторые символы встречаются чаще, чем другие. Было бы неразумно использовать это в тех случаях, когда вы действительно хотите случайность, как для паролей.
Показать ещё 5 комментариев
22

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

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.

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

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

$randstring = RandomString();
echo $randstring;

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

echo RandomString();

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

$randstring .= $characters[rand(0, strlen($characters))];
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);
  • 0
    Использование оператора по модулю % приведет к смещенному выводу. Тем не менее, сильный +1 для RandomLib. Не изобретай велосипед.
  • 1
    Да, новая функция random_int () хороша: D
9

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

Вот несколько кратчайших методов для генерации случайной строки

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

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

echo str_shuffle(MD5(microtime()));
?>
8

Я тестировал производительность большинства популярных функций там, время, необходимое для создания 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 символов.

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

7

Это было взято из источников администратора:

/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
    return md5(uniqid(mt_rand(), true));
}

Adminer, инструмент управления базами данных, написанный на PHP.

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;
}
  • 3
    Это не портативно; если вы попытаетесь запустить это в любой не-posix среде, это приведет к фатальной ошибке.
6

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

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

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

  • 0
    это просто больно ...
5

Вспомогательная функция из структуры 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);
}
  • 4
    «Не должно считаться достаточным для криптографии и т. Д.» Это должно быть сильно подчеркнуто.
4
/**
 * @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/

4

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

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

Другой однострочный, который генерирует случайную строку из 10 символов с буквами и цифрами. Он создаст массив с range (отрегулируйте второй параметр, чтобы установить размер), петли над этим массивом и назначает случайный ascii- char (диапазон 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 +

  • 0
    наконец, действительно случайное решение, а не какой-то раздутый хэш 32-битного случайного целого числа или перемешанной строки ...
  • 0
    есть только одна проблема: числа, как правило, встречаются в виде символов, что не так случайно, как хотелось бы. +1 для лучшего решения на этой странице. настроить это и его идеально.
Показать ещё 1 комментарий
4

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

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

$characters = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

в

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

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

3
function randomString($length = 5) {
       return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
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;
}
2

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

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

?>
  • 1
    Почему вы делаете $randstring глобальным, $randstring его каждый раз, а также возвращаете?
  • 0
    @Christian, потому что с пустыми вещами иногда вы можете с помощью небольших изменений в других скриптах построить структуру для получения новых вещей. Также имелась возможность получить одни и те же результаты разными способами -> это динамика развития
2

Существует простой код:

echo implode("",array_map(create_function('$s','return substr($s,mt_rand(0,strlen($s)),1);'),array_fill(0,16,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")));

Существует простое руководство:

  • Чтобы изменить длину строки, измените значение 16 на другое значение.
  • Чтобы выбрать из разных символов, измените строку символов.
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);
1

Параметрированный однострочный шрифт с использованием только родных функций 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))))))
1

Класс с некоторыми функциями из обсуждений выше.

$options['numeric'] = true;
$options['uppercase'] = true;
$options['lowercase'] = true;
$new = new RandomString($options);




class RandomString
{
    /**
     * @var array
     */
    private $default = ['numeric' => true, 'uppercase' => true, 'lowercase' => true];

    /**
     * @var array
     */
    private $options;

    /**
     * array
     */
    private $whitelist = ['numeric', 'uppercase', 'lowercase'];

    /**
     * RandomString constructor.
     *
     * @param array $options
     */
    public function __construct(array $options = [])
    {
        $this->options = $this->default;
        if(!empty($options))
        {
            $options = array_intersect_key($options, array_flip($this->whitelist));
            if(empty($options))
            {
                $this->options = $this->default;
            }else
            {
                $this->options = $options;
            }
        }

    }

    /**
     * @return string
     */
    private function returnCharacters(){

        $options = $this->options;

        $numbers = '0123456789';
        $uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $lowercase = "abcdefghijklmnopqrstuvwxyz";

        $characters = '';
        if(isset($options['numeric']) && $options['numeric'] === true){
            $characters .= $numbers;
        }

        if(isset($options['uppercase']) && $options['uppercase'] === true){
            $characters .= $uppercase;
        }

        if(isset($options['lowercase']) && $options['lowercase'] === true){
            $characters .= $lowercase;
        }
        return $characters;

    }

    /**
     * @param $length
     * @param $quantity
     * @return string
     */
    public function randomString($length, $quantity) {

        $string = '';
        $characters = $this->returnCharacters();

        for ($j = 0; $j < $quantity; $j++) {
            for($i = 0; $i < $length; $i++){
                $string .= $characters[mt_rand(0, strlen($characters) - 1)];
            }
            $string .= "\n";
        }
        return $string;
    }

    /**
     * @return array
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * @return mixed
     */
    public function getWhitelist()
    {
        return $this->whitelist;
    }
1

Наконец, я нашел решение получить случайное и уникальное значение мое решение

substr(md5(time()), 0, 12)

время всегда возвращает timstamp и всегда уникально. вы можете использовать его с md5, чтобы сделать его лучше.

  • 1
    Отметка времени не всегда уникальна, и md5 не делает ее лучше. Если несколько потоков выполняются в течение одной секунды, этот код сгенерирует одну и ту же строку для всех из них.
1

Вы делаете это совершенно неправильно, потому что вы зависите от чисел, а не символов, и я не уверен, хотите ли вы, чтобы случайный вывод был просто числом, если да, то почему нужно получить все буквы и буквы и вывести их их длина? почему бы вам просто не использовать rand(0, 62)?, даже если вы забыли инициализировать свою переменную $randstring, прежде чем объявлять эту функцию.

anyways PHP предлагает вам очень удобную функцию для этой цели str_shuffle(). Вот пример, который вам подходит.

<?php

function randomString() {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    return str_shuffle($characters);
}
echo randomString();
1

Следующая функция генерирует псевдо string из любой длины.

/**
 * Returns random string of a given length.
 */
function get_random_string($length) {
  $pull = [];
  while (count($pull) < $length) {
    $pull = array_merge($pull, range(0, 9), range('a', 'z'), range('A', 'Z'));
  }
  shuffle($pull);
  return substr(implode($pull), 0, $length);
}
1

Источник: Функция 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);
1
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
}
1

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

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

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

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

  • 2
    Конечно, time() далеко не уникален: он будет возвращать одно и то же значение снова и снова, пока не закончится текущая секунда. Что действительно обеспечивает некоторую случайность, так это str_shuffle() - остальная часть кода только уменьшает выборку, из которой выбираются символы.
  • 1
    поэтому то, что вы в основном делаете, это перемешивает 32-битное целое число. здесь не так много энтропии ...
Показать ещё 1 комментарий
1
<?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 */
  • 0
    если вы хотите использовать правильный PHP, замените первую строку функции на foreach ($ranges as $r) $s .= implode('', range(array_shift($r = explode('-', $r)), $r[1]));
0

Здесь однострочник. Вы получите как минимум одну строчную букву, одну заглавную букву, одно число и один символ. Использует random_int который должен быть киртографически защищен. Я не утверждаю, что это безопасно. Я не эксперт по безопасности.

Чтобы скопировать + вставить:

 for ($chars = array('0123456789','abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ','!@#$%^&*()_+-='),$randomString="",$i=0;$i<12;$i++)$randomString .= substr($chars[$i%4], random_int(0,strlen($chars[$i%4])), 1);

И еще немного разбитый

for (
        $chars = array('0123456789','abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ','!@#$%^&*()_+-='),
        $randomString="",
        $i=0;
        $i<12;$i++)
        $randomString .= 
            substr($chars[$i%4], 
                random_int(0, strlen($chars[$i%4])), 1);

Я использую $chars[$i%4] в цикле, чтобы выбрать набор символов для случайного выбора. Это гарантирует несколько символов из каждого набора символов в массиве.

Это, безусловно, может быть улучшено (случайное количество каждого набора символов), но этого достаточно для моих целей.

0

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

<?php
$random_string="";
$character_count=12;
for($i=1; $i<=$character_count; $i++)
{
$random_string.=chr(rand(97,122));
}
echo $random_string;
?>
0

Однострочное решение будет

str_shuffle(base64_encode(date('mdyhis').date('mdyhis')));
0

привет, вы можете попробовать это

<?php


function random($len){

    $char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    // ----------------------------------------------
    // number of possible combinations
    // ----------------------------------------------
    $pos = strlen($char);
    $pos = pow($pos, $len);
    echo $pos.'<br>';
    // ----------------------------------------------

    $total = strlen($char)-1;
    $text = "";

    for ($i=0; $i<$len; $i++){
        $text = $text.$char[rand(0, $total)];
    }

    return $text;

}


$string = random(15);
echo $string;



?>

вы также можете использовать md5 вовремя, но будьте осторожны вам нужно использовать функцию microtime(), а не time(), потому что если несколько потоков выполняются в течение одной секунды, вам нужно получить другую строку для всех из них.

<?php

    $string = md5( microtime() );
    echo $string;

?>
0

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

  • 1
    Кроме того, я бы добавил, что вы не должны включать визуально похожие символы, например, 1=>l (lowercase L), 0 (digit)=>O (letter) . Это может сбить пользователя с толку, так как на первый взгляд они похожи, поэтому придерживайтесь только отдельных.
0
function randomString() {
       return md5(rand(100, 200));
}
  • 1
    Это только частично случайно, так как вы ограничиваете его до 100 уникальных комбинаций. Кроме того, md5 всегда будет возвращать строку длиной 32 символа. Подходит для общего использования, но не для большого количества действительно уникальных строк. Смотрите мой ответ для примера с лучшей случайностью, используя текущее время, md5 () и base64_decode() .
0
function randomName($length = 8) {
  $values = array_merge(range(65, 90), range(97, 122), range(48, 57));
  $max = count($values) - 1;
  $str = chr(mt_rand(97, 122));
  for ($i = 1; $i < $length; $i++) {
    $str .= chr($values[mt_rand(0, $max)]);
  }
  return $str;
}
-1

Вам нравится получать его в одной строке?

Попробуйте это,

$str = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 5)), 0, $length);
  • 0
    После 65 536 случайных строк, сгенерированных таким образом, можно ожидать, что они сгенерировали одну и ту же строку дважды, даже с произвольно большой $length . Слабые PRNG приводят к столкновениям (и предсказуемы!)
  • 0
    str_shuffle - случайным образом перемешивает строку в соответствии с документами PHP. Итак, как вы могли бы сказать, что это не будет одна и та же строка дважды.
-1

Если вам нужно большое количество случайных строк без дубликатов, здесь рекурсивный код с небольшой модификацией:

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

$generatedStrings = array();

foreach(range(1, 100000) as $num) {
    echo "\n".$num."\t : ".generateRandomString();
}
-1

Я говорю, беру лучшее из нескольких ответов и собираю их вместе - str_suffle и range новы для меня:

echo generateRandomString(25); // Example of calling it

function generateRandomString($length = 10) {
    return substr(str_shuffle(implode(array_merge(range(0,9), range('A', 'Z'), range('a', 'z')))), 0, $length);
}
  • 2
    Это ограничено 62 символами, потому что вы просто объединяете 3 диапазона (0-9, az, AZ) в строку длиной 62, а затем перетасовываете символы и получаете первые N символов (так что N может быть в большинство 62). Функция может быть переработана, чтобы сделать рекурсивный вызов самому себе, когда запрашивается длина более 62 символов, но он просто хотел указать текущий предел для любого, кто читает это.
  • 0
    много усилий для небольшой энтропии здесь ... вы можете сделать лучше, чем это.
-2

Предыдущие ответы генерируют пароли, которые небезопасны или сложны для ввода.

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

// NOTE: On PHP 5.x you will need to install https://github.com/paragonie/random_compat

/**
 * Generate a password that can easily be typed by users.
 *
 * By default, this will sacrifice strength by skipping characters that can cause
 * confusion. Set $allowAmbiguous to allow these characters.
 */
static public function generatePassword($length=12, $mixedCase=true, $numericCount=2, $symbolCount=1, $allowAmbiguous=false, $allowRepeatingCharacters=false)
{
  // sanity check to prevent endless loop
  if ($numericCount + $symbolCount > $length) {
    throw new \Exception('generatePassword(): $numericCount + $symbolCount are too high');
  }

  // generate a basic password with just alphabetic characters
  $chars  = 'qwertyupasdfghjkzxcvbnm';
  if ($mixedCase) {
    $chars .= 'QWERTYUPASDFGHJKZXCVBNML';
  }
  if ($allowAmbiguous) {
    $chars .= 'iol';
    if ($mixedCase) {
      $chars .= 'IO';
    }
  }

  $password = '';
  foreach (range(1, $length) as $index) {
    $char = $chars[random_int(0, strlen($chars) - 1)];

    if (!$allowRepeatingCharacters) {
      while ($char == substr($password, -1)) {
        $char = $chars[random_int(0, strlen($chars) - 1)];
      }
    }

    $password .= $char;
  }


  // add numeric characters
  $takenSubstitutionIndexes = [];

  if ($numericCount > 0) {
    $chars = '23456789';
    if ($allowAmbiguous) {
      $chars .= '10';
    }

    foreach (range(1, $numericCount) as $_) {
      $index = random_int(0, strlen($password) - 1);
      while (in_array($index, $takenSubstitutionIndexes)) {
        $index = random_int(0, strlen($password) - 1);
      }

      $char = $chars[random_int(0, strlen($chars) - 1)];
      if (!$allowRepeatingCharacters) {
        while (substr($password, $index - 1, 1) == $char || substr($password, $index + 1, 1) == $char) {
          $char = $chars[random_int(0, strlen($chars) - 1)];
        }
      }

      $password[$index] = $char;
      $takenSubstitutionIndexes[] = $index;
    }
  }

  // add symbols
  $chars = '!@#$%&*=+?';
  if ($allowAmbiguous) {
    $chars .= '^~-_()[{]};:|\\/,.\'"`<>';
  }

  if ($symbolCount > 0) {
    foreach (range(1, $symbolCount) as $_) {
      $index = random_int(0, strlen($password) - 1);
      while (in_array($index, $takenSubstitutionIndexes)) {
        $index = random_int(0, strlen($password) - 1);
      }

      $char = $chars[random_int(0, strlen($chars) - 1)];
      if (!$allowRepeatingCharacters) {
        while (substr($password, $index - 1, 1) == $char || substr($password, $index + 1, 1) == $char) {
          $char = $chars[random_int(0, strlen($chars) - 1)];
        }
      }

      $password[$index] = $char;
      $takenSubstitutionIndexes[] = $index;
    }
  }

  return $password;
}
  • 0
    никто не просил функцию пароля
-2

Мне всегда нравилось использовать base64 для генерации случайных паролей или других случайных (печатных) символов. Использование base64 обеспечивает доступность большого количества печатных символов.

В оболочке я обычно делаю что-то вроде этого:

base64 < /dev/urandom |head -c10

Нечто похожее может быть сделано и на PHP. Однако чтение непосредственно из /dev/urandom может быть запрещено ограничениями open_basedir. Итак, вот что я достиг:

base64_encode(
    join(
        '',
        array_map(
            function($x){ return chr(mt_rand(1,255));},
            range(1,15)
        )
    )
);

Чтобы получить действительно случайную строку, нам нужен случайный ввод. Это то, что делает join/array_map. Использовать что-то вроде uniqid недостаточно, потому что он всегда будет иметь похожий префикс, так как это в основном прославленная метка времени.

Если у вас установлено расширение openssl, вы можете, конечно, использовать openssl_random_pseudo_bytes(), что было бы еще лучше.

  • 0
    Да, используйте openssl_random_pseudo_bytes() если можете! Не соглашайтесь на mt_rand mt_rand() , посмотрите этот ответ для реализации, которая использует CSPRNG.
-2
$t = array_merge(range('0', '9'), range('a', 'z'), range('A', 'Z'));
echo join('', array_map(function() use($t) { return $t[array_rand($t)]; }, range(1, 15)));

или однострочный

echo join('', array_map(function() { return substr('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', rand(0, 61), 1); }, range(1, 15)));
-2

попробуйте следующее:

function generate_name ($length = LENGTH_IMG_PATH) {
    $image_name = "";
    $possible = "0123456789abcdefghijklmnopqrstuvwxyz";

    $i = 0;

    while ($i < $length) {

        $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);

        if (!strstr($image_name, $char)) {
            $image_name .= $char;
            $i++;               
        }              
    }            
    return $image_name;
}     
-3
$pass = "";
for ($i=0;$i<12;++$i)
  $pass.= ($r=mt_rand(0,35))<26?chr(ord('a')+$r):chr(ord('0')+$r-26);
  • 0
    решение одной линии
  • 0
    $pass = ""; линия пропущена :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню