Gerador de string aleatória PHP

814

Estou tentando criar uma string aleatória no PHP e não recebo absolutamente nenhuma saída com isso:

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

    RandomString();
    echo $randstring;

O que estou fazendo errado?

Capitão Relâmpago
fonte
241
Minha solução de uma linha para gerar string curta é substr (md5 (rand ()), 0, 7); sorte ...
tasmaniski
5
@tasmaniski .. Sua solução está ok .. Mas é menos aleatória! No seu exemplo, o número de seqüências aleatórias que podem ser geradas é limitado pelo tamanho do número inteiro. (2 ^ 32) no máximo. No caso da outra solução, você pode gerar (62 ^ 8). Caso deseje cadeias maiores, o número de cadeias distintas permanecerá no máximo 2 ^ 32, mas no outra solução que aumenta a (62 ^ n) ..
Manu
9
Você esqueceu de adicionar cada novo caractere gerado à string. Você está apenas substituindo-o como está. Deve ser de US $ randstring = $ personagens ...
Spock
3
@CaptainLightning Você pode trocar a resposta aceita por uma das mais seguras? :)
Scott Arciszewski
2
strlen($characters)=> strlen($characters) - 1- o comprimento da string começa com 1
Zippp 24/04

Respostas:

1394

Para responder especificamente a essa pergunta, dois problemas:

  1. $randstring não está no escopo quando você faz o eco.
  2. Os caracteres não estão sendo concatenados juntos no loop.

Aqui está um trecho de código com as correções:

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

Emita a sequência aleatória com a chamada abaixo:

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

Observe que isso gera seqüências aleatórias previsíveis. Se você deseja criar tokens seguros, consulte esta resposta .

Stephen Watkins
fonte
34
@FranciscoPresencia, é melhor "desperdiçar" uma variável extra ao chamar um método na condição de comparação de um loop.
Rico Sonntag
200
Todo esse trabalho, por que não apenas algo assim substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH 9/04
4
Obrigado pelo código, mas mude rand()paramt_rand() . Eu usei seu método e experimentei uma tonelada de colisões com nomes.
Nate
5
@FranciscoPresencia, você tem alguma ideia de como isso é terrivelmente ineficiente? Você está verificando o comprimento de uma string duas vezes por iteração! O strlen dentro do loop deve ser armazenado em cache em uma variável antes de entrar no loop também.
developerbmw
4
Esta não é uma boa solução. As strings que isso gera serão previsíveis. :(
Scott Arciszewski
370

Nota: str_shuffle()usa internamente rand(), o que não é adequado para fins de criptografia (por exemplo, gerar senhas aleatórias). Você deseja um gerador de números aleatórios seguro . Também não permite que os caracteres se repitam.

Mais uma maneira.

ATUALIZADO (agora isso gera qualquer comprimento de string):

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

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

É isso aí. :)

A. Cheshirov
fonte
64
+1 para a resposta mais curta :). Mas não é a melhor resposta para todos os casos de uso. Esse código produzirá seqüências de caracteres em que cada caractere não aparecerá mais de uma vez (tornando-o mais fraco para ataques de força bruta) e não produzirá nada além de 62 caracteres.
David
17
Não faça isso, é extremamente fraco. Quanto mais tempo você criar sua sequência aleatória, mais fraca será.
Abhi Beckert
23
Pode ser fraco, mas é rápido e fácil. Dependendo do caso de uso, tudo bem - usei porque não precisava de segurança ou força; apenas um shuffle rápido. Estou escrevendo um teste de unidade, e isso me dá uma entrada aleatória adequada para testar.
SDC
23
@FranciscoPresencia a razão pela qual não é seguro é porque nunca usa o mesmo caractere duas vezes. Isso o torna um terrível gerador de senhas. Por favor, todos parem de votar, é totalmente inseguro e nunca deve ser usado. À medida que a senha aumenta, o número de caracteres que você deve testar com força bruta fica menor porque você não se incomoda em testar nenhum caractere usado anteriormente.
Abhi Beckert
8
@FranciscoPresencia: apoio seus comentários sobre como evitar o uso de senhas aleatórias. No entanto, discordo que esta resposta não deve ser mais do que uma. Marquei esta opção como uma solução efetiva de uma linha para gerar seqüências aleatórias (o tópico original desta pergunta).
bwright
331

Há muitas respostas para essa pergunta, mas nenhuma delas utiliza um gerador de números pseudo-aleatórios criptograficamente seguros (CSPRNG).

A resposta simples, segura e correta é usar o RandomLib e não reinventar a roda.

Para aqueles que insistem em inventar sua própria solução, o PHP 7.0.0 fornecerá random_int()esse propósito; se você ainda usa o PHP 5.x, criamos um polyfill do PHP 5 pararandom_int() que você possa usar a nova API antes de atualizar para o PHP 7.

Gerar números inteiros aleatórios com segurança no PHP não é uma tarefa trivial. Você deve sempre verificar com os especialistas em criptografia StackExchange residentes antes de implantar um algoritmo caseiro na produção.

Com um gerador inteiro seguro no lugar, gerar uma sequência aleatória com um CSPRNG é uma caminhada no parque.

Criando uma seqüência aleatória segura

/**
 * 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);
}

Uso :

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

Demo : https://3v4l.org/IMJGF (Ignore as falhas do PHP 5; ele precisa de random_compat)

Scott Arciszewski
fonte
3
No início da função, adicione $keyspace = str_shuffle($keyspace );mais segurança
Jevgenij Dmitrijev 16/04
13
O que você quer dizer com "para mais segurança"? Já estamos usando um gerador de números aleatórios seguro.
23917 Scott Scallisz escreveu uma avaliação a
5
@JGEstiot A criação de seqüências aleatórias com segurança requer aleatoriedade criptograficamente segura. Alguém pesquisando "como gerar seqüências aleatórias em PHP" é mais bem atendido por uma resposta segura do que por uma resposta insegura.
Scott Arciszewski 30/03
1
@ Scott Arciszewski Você não precisa criar cadeias aleatórias criptograficamente sempre que cria cadeias aleatórias. A pergunta era sobre a criação de seqüências aleatórias e isso não tem nada a ver com segurança. Você presumiu que a string seria usada em um contexto sensível à segurança e adicionou uma camada de complexidade que afasta o núcleo da pergunta.
JG Estiot
45
Usar em random_int()vez de rand()ou mt_rand()não adiciona complexidade ao desenvolvedor. Ao mesmo tempo, oferece maior segurança. As pessoas que vêm ao StackOverflow procurando soluções rápidas podem não saber se o que estão construindo precisa ser seguro ou não. Se lhes dermos respostas seguras por padrão, elas criarão uma Internet mais segura, mesmo que, de sua perspectiva, seja totalmente acidental. Por que você se oporia a esse objetivo é um mistério para mim.
Scott Arciszewski
156

Isso cria uma cadeia hexadecimal de 20 caracteres:

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

No 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
fonte
Observe que openssl_random_pseudo_bytes()não utilizou um algoritmo criptograficamente forte até o php 5.6. Erro relacionado: bugs.php.net/bug.php?id=70014
acidtv 8/08/16
Observe também que a menor string que isso pode criar é do comprimento 2. Se você passar um byte de 1 ou menos para openssl_random_pseudo_bytes()você, não receberá nada de volta. Além disso, observe que ao usar bin2hex(openssl_random_pseudo_bytes($length / 2))desde que você está trabalhando com números inteiros, ele removerá automaticamente o módulo e usará o próximo múltiplo mais baixo de 2. Portanto, $length = 19produzirá uma sequência de comprimento 18.
Nathan F.
Proposta para usá-lo como conteúdo de arquivo que pode ser aberto através de fgets($fp, 1024)todos os editores de arquivos com problemas com linhas muito longas: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }defina $splitcomo nullse deve retornar uma linha única. Com isso, você pode usá-lo nos dois casos.
mgutt
Eu realmente gosto da solução random_bytes do PHP 7, mas se você precisar que a string tenha um certo número de caracteres, algo assim funcionaria? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programster
Esta é sem dúvida a melhor solução. Ocupa muito pouco espaço e é super fácil de entender.
Matthew Campbell
92

@tasmaniski: sua resposta funcionou para mim. Eu tive o mesmo problema, e eu o sugeriria para quem está sempre procurando a mesma resposta. Aqui é de @tasmaniski:

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

Aqui está um vídeo do youtube mostrando como criar um número aleatório

Humphrey
fonte
6
se sua string é baseada apenas em um número inteiro aleatório, por que não usar apenas o número inteiro aleatório? o palheiro não fica mais fundo misturando-o ... e cortando o hash de você realmente desminam a pequena entropia com a qual você tinha que começar.
O Surrican
4
Lembre-se de md5que resultará em um limite de 30 caracteres e sempre em minúsculas.
precisa
3
Além disso, rand () não deve ser usado para criptografia. Se você deseja gerar uma sequência criptograficamente correta, use openssl_random_pseudo_bytes .
mattkgross
md5(rand())oferece apenas 2 ^ 32 valores possíveis. Isso significa que, após, em média, 2 ^ 16 seqüências aleatórias, espera-se que você repita.
23915 Scott Scalles
2
Bem ... eu apostaria que o OP não está falando sobre "seqüências aleatórias seguras". Esta solução é compacta, fácil e bonita de lembrar, para os casos de uso corretos . E, se você precisar cuidar de possíveis colisões, por que não acrescentar / acrescentar um carimbo de data / hora à sequência aleatória? :)
Erenor Paz
46

Dependendo da sua aplicação (eu queria gerar senhas), você poderia usar

$string = base64_encode(openssl_random_pseudo_bytes(30));

Sendo base64, eles podem conter =ou -os caracteres solicitados. Você pode gerar uma sequência mais longa, filtrar e aparar para removê-las.

openssl_random_pseudo_bytesparece ser a maneira recomendada de gerar um número aleatório adequado em php. Por randque não usa /dev/randomeu não sei.

rjmunro
fonte
2
O rand não usa / dev / urandom porque está disponível apenas em ambientes como o posix e não é portátil.
Macroman
3
@ MacroMan Mas openssl_random_pseudo_bytes() é portátil.
Ja͢ck
Se você quiser retirar os base64 caracteres extras, tente o seguinte: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley
3
Isso não está errado, mas eu recomendaria cautela ao descartar os caracteres indesejados. Veja esta solicitação de recebimento no servidor OAuth2 da liga PHP , por exemplo.
Scott Arciszewski
Esta é uma das melhores respostas. Pena que não tem mais apoio. Eu recomendaria editar sua resposta para lidar melhor com caracteres indesejados.
Jcuenod
28

Aqui está uma linha única simples que gera uma verdadeira sequência aleatória sem nenhum loop de nível de script ou uso de bibliotecas OpenSSL.

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

Para dividi-lo para que os parâmetros sejam claros

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

Esse método funciona repetindo aleatoriamente a lista de caracteres, embaralha a seqüência combinada e retorna o número de caracteres especificado.

Você pode randomizar isso ainda mais, randomizando o comprimento da sequência retornada, substituindo $chrRandomLengthpor mt_rand(8, 15)(para uma sequência aleatória entre 8 e 15 caracteres).

Kraang Prime
fonte
lamento dizer, mas quando um personagem seleciona sua probabilidade de ocorrer novamente não é tão alta quanto os outros personagens que ainda permanecem no pool. há verdadeira aleatoriedade aqui ...
A Surrican
@ TheSurrican - Você estaria incorreto nessa declaração. Todos os caracteres têm uma probabilidade igual de usar esse algoritmo e, portanto, são verdadeiramente aleatórios. Isso é garantido repetindo a string chrList $ chrRepeatMax, e a mágica realmente acontece em str_shuffle, que determina a aleatoriedade.
Kraang Prime
Todos os caracteres que aparecem apenas uma vez e é muito propenso a bruteforce palpite
venimus
@venimus Isso está incorreto. A string de caracteres é duplicada para quantos caracteres você deseja (veja $chrRepeatMaxe $chrRepeatMin) - portanto, uma string de 10 caracteres poderia (improvável, mas possível) ser "aaaaaaaaaa".
Kraang Prime
@SanuelJackson Desculpe, mas comentei. Eu coloquei o comentário na resposta errada. Você está certo! Na verdade, eu usei o seu "truque", mas não usei o mt_rand, porque é IMHO inútil. Não adiciona à entropia. Apenas usei const com o comprimento máximo.
venimus
25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Tada!

Davor
fonte
Lembre-se de sha1que o limite de 40 caracteres será sempre minúsculo.
precisa
3
Se as strings sha1 não forem aleatórias, certos caracteres ocorrerão com mais frequência que outros. Seria imprudente usar isso nos casos em que você realmente deseja aleatoriedade, como nas senhas.
precisa
1
@KitSunde - sim, sha não é aleatório, rand () é aleatório. E sha é perfeitamente adequado para o que é necessário aqui. O OP não precisa de nível criptográfico de aleatoriedade.
Davor
@ Davor rant()ser aleatório não importa quando sha não é distribuído uniformemente. Se você selecionar aleatoriamente a partir de uma distribuição desigual, obterá exatamente a mesma distribuição desigual. Não estou destacando a aleatoriedade no "nível de criptografia", se esse também não era o caso rand(). É preciso um esforço mínimo para obter uma distribuição uniforme, como na resposta aceita, e é tão aleatório quanto rand () razoavelmente.
Kit Sunde
@KitSunde - literalmente não faz diferença no final. Essa é exatamente a definição de superengenharia e revestimento de ouro.
Davor
24

Uma maneira melhor de implementar essa função é:

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é mais aleatório de acordo com isso e isso no PHP 7. A randfunção é um alias de mt_rand.

Rathienth Baskaran
fonte
1
Cuidado: mt_randnão gera valores criptograficamente seguros. Para isso, você deve usar PHP7 random_intou random_bytes.
jchook
18

$randstringno escopo da função não é igual ao escopo em que você o chama. Você precisa atribuir o valor de retorno a uma variável.

$randstring = RandomString();
echo $randstring;

Ou apenas faça eco diretamente no valor de retorno:

echo RandomString();

Além disso, em sua função, você tem um pequeno erro. Dentro do loop for, você precisa usar .=para que cada caractere seja anexado à string. Ao usá- =lo, você o substituirá com cada novo caractere, em vez de anexá-lo.

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

Primeiro, você define o alfabeto que deseja usar:

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

Em seguida, use openssl_random_pseudo_bytes()para gerar dados aleatórios adequados:

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

Por fim, você usa esses dados aleatórios para criar a senha. Como cada caractere $randompode durar chr(0)até chr(255), o código usa o restante após a divisão de seu valor ordinal com $alphabet_lengthpara garantir que apenas os caracteres do alfabeto sejam escolhidos (observe que isso influencia a aleatoriedade):

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

Como alternativa, e geralmente melhor, é usar RandomLib e SecurityLib :

use SecurityLib\Strength;

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

$password = $generator->generateString(12, $alphabet);
Ja͢ck
fonte
O uso do operador de módulo %produzirá saída tendenciosa. No entanto, +1 forte para RandomLib. Não reinvente a roda.
Scott Arciszewski
1
Sim, a nova função random_int () é interessante: D
Ja͢ck
11

Métodos curtos ..

Aqui estão alguns métodos mais curtos para gerar a string aleatória

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

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

echo str_shuffle(MD5(microtime()));
?>
Punit Gajjar
fonte
10

Eu testei o desempenho das funções mais populares lá, o tempo necessário para gerar 1'000'000 strings de 32 símbolos na minha caixa é:

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

Observe que não é importante quanto tempo realmente durou, mas qual é mais lento e qual é mais rápido, para que você possa selecionar de acordo com seus requisitos, incluindo prontidão para criptografia etc.

substr () ao redor do MD5 foi adicionado para garantir a precisão, se você precisar de uma string menor que 32 símbolos.

Por uma questão de resposta: a sequência não foi concatenada, mas substituída e o resultado da função não foi armazenado.

Putnik
fonte
Eu acho que é a melhor resposta. Obrigado!
NSukonny 23/05/19
10

PHP 7+ Gere bytes aleatórios criptograficamente seguros usando a função random_bytes .

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

Saída possível

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ Gere bytes pseudo-aleatórios usando a função openssl_random_pseudo_bytes .

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

Saída possível

e2d1254506fbb6cd842cd640333214ad


O melhor caso de uso pode ser

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

Saída possível

ba8cc342bdf91143

Madan Sapkota
fonte
Isso não irá gerar uma string com o comprimento especificado
Timberman
@ Timberman, ele irá gerar o comprimento exato agora.
Madan Sapkota
9

Uma maneira muito rápida é fazer algo como:

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

Isso irá gerar uma sequência aleatória com o comprimento de 10 caracteres. Certamente, alguns podem dizer que é um pouco mais pesado no lado da computação, mas hoje em dia os processadores são otimizados para executar o algoritmo md5 ou sha256 muito rapidamente. E, é claro, se a rand()função retornar o mesmo valor, o resultado será o mesmo, com uma chance de 1/32767 de ser o mesmo. Se a segurança é o problema, basta alterar rand()paramt_rand()

Akatosh
fonte
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;
}
Руслан Ибрагимов
fonte
4
Isso não é portátil; se você tentar executar isso em qualquer ambiente não-posix, isso causará um erro fatal.
Bryan Agee
7

Este foi retirado de fontes de administrador :

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

Adminer , ferramenta de gerenciamento de banco de dados escrita em PHP.

userlond
fonte
6

Função auxiliar do framework 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
fonte
4
"Não deve ser considerado suficiente para criptografia, etc." Isso deve ser enfatizado fortemente.
23915 Scott Scalles
4

A versão editada da função funciona bem, mas encontrei apenas um problema: você usou o caractere errado para incluir $ caracteres; portanto, o caractere 'às vezes faz parte da sequência aleatória gerada.

Para corrigir isso, altere:

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

para:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

Dessa forma, apenas os caracteres incluídos são usados ​​e o caractere 'nunca fará parte da sequência aleatória gerada.

bmcswee
fonte
4

Outra linha, que gera uma sequência aleatória de 10 caracteres com letras e números. Ele criará uma matriz com range(ajuste o segundo parâmetro para definir o tamanho), passa por essa matriz e atribui um caractere ASCII aleatório (intervalo de 0 a 9 ou az) e depois implode a matriz para obter uma sequência.

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

Nota: isso funciona apenas no PHP 5.3 e posterior

Kasimir
fonte
finalmente uma solução verdadeiramente aleatório não algum haxixe inchada de um inteiro de 32 bits aleatório ou uma string baralhados ...
O Surrican
há apenas uma questão: os números são tão prováveis ​​de ocorrer quanto os caracteres, o que não é tão aleatório quanto eu gostaria de ter. anyaway +1 para a melhor solução nesta página. ajustar isso e é perfeito.
The Surrican
ajustar ... assim? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth
4

Um forro.

É rápido para cordas enormes com alguma exclusividade.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
Jacob Smith
fonte
md5(rand())é uma maneira terrivelmente insegura de gerar um número aleatório.
23915 Scott Scalles
1
uma string com comprimento X e alguma exclusividade é a intenção. aleatoriedade verdadeira não é a intenção.
27675 Jacob
3

Gostei do último comentário que usou o openssl_random_pseudo_bytes, mas não foi uma solução para mim, pois ainda tinha que remover os caracteres que não queria e não consegui obter uma string de comprimento definido. Aqui está a minha solução ...

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

Aqui está minha solução simples de uma linha para gerar uma senha aleatória amigável para o uso, excluindo caracteres semelhantes a "1" e "l", "O" e "0", etc ... aqui estão 5 caracteres, mas você pode facilmente mude de curso:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);
rAthus
fonte
Isso é perfeito para criar seqüências de ID aleatórias para chamar mais tarde no jquery. IDK se a sua boa prática, mas isso me ajudou muito, sem usar um para como a resposta aceita ...
Rodrigo Zuluaga
3

Aqui está outra solução.

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. Estou usando o PHP 7.2 no Ubuntu.

Umair Khan
fonte
2

Outra maneira de gerar uma string aleatória no 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);
Akhilraj NS
fonte
2

Aqui está como eu estou fazendo isso para obter uma chave aleatória única e verdadeira:

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

Você pode usar time (), pois é um carimbo de data / hora do Unix e sempre é único em comparação com outros aleatórios mencionados acima. Em seguida, você pode gerar o md5sum e obter o comprimento desejado da cadeia MD5 gerada . Nesse caso, estou usando 10 caracteres e poderia usar uma string mais longa se quiser torná-la mais exclusiva.

Eu espero que isso ajude.

sherpa
fonte
2
Obviamente, time()está longe de ser único: ele retornará o mesmo valor repetidamente até o final do segundo atual. O que realmente fornece alguma aleatoriedade aqui é: o str_shuffle()restante do código reduz apenas a amostra para a seleção de caracteres.
Álvaro González
1
então o que você está basicamente fazendo é embaralhar um número inteiro de 32 bits. não muita entropia aqui ...
The Surrican
2
Um invasor pode adivinhar o valor retornado por time()(é apenas um carimbo de data / hora), é uma fonte fraca de aleatoriedade.
AL
2

One-liner parametrizado usando apenas funções nativas do PHP , trabalhando desde o 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
fonte