Generador de cadenas aleatorias PHP

814

Estoy tratando de crear una cadena aleatoria en PHP, y no obtengo absolutamente ningún resultado con esto:

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

    RandomString();
    echo $randstring;

¿Qué estoy haciendo mal?

Capitán Rayo
fuente
241
Mi solución de una línea para generar una cadena corta es substr (md5 (rand ()), 0, 7); buena suerte ...
tasmaniski
55
@tasmaniski ... Tu solución está bien ... ¡Pero es menos aleatoria! En su ejemplo, el número de cadenas aleatorias que se pueden generar está limitado por el tamaño del número entero. (2 ^ 32) al máximo .. En el caso de la otra solución, puede generar (62 ^ 8) .. En caso de que quiera cadenas más grandes, entonces el número de cadenas distintas permanece en el máximo 2 ^ 32, pero en el otra solución aumenta a (62 ^ n) ..
Manu
99
Olvidó agregar cada nuevo carácter generado a la cadena. Lo estás sobrescribiendo tal como está. Debe ser $ randstring. = $ Caracteres ..
Spock
3
@CaptainLightning ¿Puede cambiar la respuesta aceptada por una de las más seguras? :)
Scott Arciszewski
2
strlen($characters)=> strlen($characters) - 1- la longitud de la cadena comienza con 1
Zippp

Respuestas:

1394

Para responder esta pregunta específicamente, dos problemas:

  1. $randstring no está dentro del alcance cuando lo repites.
  2. Los personajes no se concatenan juntos en el bucle.

Aquí hay un fragmento de código con las correcciones:

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

Salida de la cadena aleatoria con la siguiente llamada:

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

Tenga en cuenta que esto genera cadenas aleatorias predecibles. Si desea crear tokens seguros, vea esta respuesta .

Stephen Watkins
fuente
34
@FranciscoPresencia, es mejor "desperdiciar" una variable adicional a partir de llamar a un método en la condición de comparación de un bucle.
Rico Sonntag
200
Todo ese trabajo, ¿por qué no simplemente algo así substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH
44
Gracias por el código, pero cambie rand()a mt_rand(). Usé tu método y experimenté un montón de colisiones con nombres.
Nate
55
@FranciscoPresencia, ¿tienes idea de lo horriblemente ineficiente que es eso? ¡Está comprobando la longitud de una cadena dos veces por iteración! El strlen dentro del bucle debe almacenarse en caché en una variable antes de entrar también en el bucle.
developerbmw
44
Esta no es una buena solución. Las cadenas que esto genera serán predecibles. :(
Scott Arciszewski
370

Nota: str_shuffle()utiliza internamente rand(), lo que no es adecuado para fines de criptografía (por ejemplo, generar contraseñas aleatorias). Desea un generador de números aleatorios seguro en su lugar. Tampoco permite que los personajes se repitan.

Una forma mas.

ACTUALIZADO (ahora esto genera cualquier longitud de cadena):

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

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

Eso es. :)

A. Cheshirov
fuente
64
+1 para la respuesta más corta :). Pero no es la mejor respuesta para cada caso de uso. Este código generará cadenas donde cada personaje no aparecerá más de una vez (lo que lo hará más débil para los ataques de fuerza bruta) y no generará más de 62 caracteres.
David
17
No hagas esto, es extremadamente débil. Cuanto más tiempo hagas tu secuencia aleatoria, más débil será.
Abhi Beckert
23
Puede ser débil, pero es rápido y fácil. Dependiendo del caso de uso, esto está bien: lo he usado porque no necesitaba seguridad ni fortaleza; solo un shuffle de fuego rápido. Estoy escribiendo una prueba unitaria, y esto me da una entrada aleatoria adecuada para probar.
COSUDE
23
@FranciscoPresencia la razón por la que no es segura es porque nunca usa el mismo personaje dos veces. Eso lo convierte en un terrible generador de contraseñas. Por favor, todos dejen de votar esto, es totalmente inseguro, nunca se debe usar. A medida que la contraseña se alarga, la cantidad de caracteres que debe probar en una fuerza bruta se acorta porque no se molesta en probar ningún carácter utilizado anteriormente.
Abhi Beckert el
8
@FranciscoPresencia: apoyo sus comentarios sobre evitar usar esto para contraseñas aleatorias. Sin embargo, no estoy de acuerdo con que esta respuesta no sea de más uno. Tengo más una opción para esta opción, ya que es una solución eficaz de una línea para generar cadenas aleatorias (el tema original de esta pregunta).
bwright
331

Hay muchas respuestas a esta pregunta, pero ninguna de ellas aprovecha un generador de números pseudoaleatorios criptográficamente seguros (CSPRNG).

La respuesta simple, segura y correcta es usar RandomLib y no reinventar la rueda.

Para aquellos de ustedes que insisten en inventar su propia solución, PHP 7.0.0 proporcionará random_int()para este propósito; si todavía está en PHP 5.x, escribimos un polyfill de PHP 5 pararandom_int() que pueda usar la nueva API incluso antes de actualizar a PHP 7.

La generación segura de enteros aleatorios en PHP no es una tarea trivial. Siempre debe consultar con sus expertos en criptografía StackExchange residentes antes de implementar un algoritmo interno en producción.

Con un generador entero seguro en su lugar, generar una cadena aleatoria con un CSPRNG es un paseo por el parque.

Crear una cadena segura y aleatoria

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

Demostración : https://3v4l.org/IMJGF (ignore las fallas de PHP 5; necesita random_compat)

Scott Arciszewski
fuente
3
Al comienzo de la función agregar $keyspace = str_shuffle($keyspace );para más seguridad
Jevgenij Dmitrijev
13
¿Qué quiere decir con "para mayor seguridad"? Ya estamos usando un generador de números aleatorios seguro.
Scott Arciszewski
55
@JGEstiot Crear cadenas aleatorias seguras requiere aleatoriedad criptográficamente segura. Alguien que busca "cómo generar cadenas aleatorias en PHP" se sirve mejor con una respuesta segura que con una respuesta insegura.
Scott Arciszewski
1
@ Scott Arciszewski No es necesario crear cadenas criptográficamente aleatorias cada vez que crea cadenas aleatorias. La pregunta era sobre la creación de cadenas aleatorias y esto no tiene nada que ver con la seguridad. Asumió que la cadena se usará en un contexto sensible a la seguridad y agrega una capa de complejidad que disuade al núcleo de la pregunta.
JG Estiot
45
Usar en random_int()lugar de rand()o mt_rand()no agrega complejidad para el desarrollador. Al mismo tiempo, les da mayor seguridad. Las personas que vienen a StackOverflow en busca de soluciones rápidas pueden no saber si lo que están construyendo necesita ser seguro o no. Si les damos respuestas seguras por defecto, crean una Internet más segura incluso si, desde su perspectiva, es totalmente accidental. Por qué te opondrías a este objetivo es un misterio para mí.
Scott Arciszewski
156

Esto crea una cadena hexadecimal de 20 caracteres de longitud:

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

En 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
fuente
Tenga en cuenta que openssl_random_pseudo_bytes()no utilizó un algoritmo criptográficamente fuerte hasta php 5.6. Error
acidtv
También tenga en cuenta que la cadena más pequeña que puede hacer es de longitud 2. Si pasa una longitud de byte de 1 o menos openssl_random_pseudo_bytes(), no obtendrá nada. Además, tenga en cuenta que al usarlo bin2hex(openssl_random_pseudo_bytes($length / 2))ya que está trabajando con enteros, eliminará automáticamente el módulo y usará el siguiente múltiplo más bajo de 2. Por lo tanto, $length = 19producirá una cadena de longitud 18.
Nathan F.
Propuesta para utilizarlo como el contenido del archivo que se puede abrir a través fgets($fp, 1024)y cada editor de archivos que tiene problemas con las líneas muy largas: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }Conjunto $splitde nullsi se debe devolver una sola línea. Por eso puedes usarlo en ambos casos.
mgutt
Realmente me gusta la solución random_bytes para PHP 7, pero si necesita que la cadena tenga un cierto número de caracteres, ¿funcionaría algo así? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programador
Esta es sin duda la mejor solución. Ocupa muy poco espacio y es muy fácil de entender.
Matthew Campbell
92

@tasmaniski: tu respuesta funcionó para mí. Tuve el mismo problema y lo sugeriría para aquellos que alguna vez buscan la misma respuesta. Aquí es de @tasmaniski:

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

Aquí hay un video de YouTube que nos muestra cómo crear un número aleatorio

Humphrey
fuente
66
si su cadena se basa solo en un número entero aleatorio, ¿por qué no usar el número entero aleatorio? el pajar no se hace más profundo al cortarlo ... y al cortar el hash de ti en realidad minas la pequeña entropía con la que tenías que comenzar.
The Surrican
44
Tenga en cuenta que md5dará como resultado un límite de 30 caracteres y siempre caracteres en minúsculas.
fyrye
3
Además, rand () no debe usarse para la criptografía. Si está buscando generar una cadena de sonido criptográfico, use openssl_random_pseudo_bytes .
mattkgross
md5(rand())solo ofrece 2 ^ 32 valores posibles. Esto significa que después de, en promedio, 2 ^ 16 cadenas aleatorias, esperará que se repita una.
Scott Arciszewski
2
Bueno ... apuesto a que el OP no está hablando de "cadenas aleatorias seguras". Esta solución es compacta, fácil y bonita de recordar, para los casos de uso correctos . Y, si necesita ocuparse de posibles colisiones, ¿por qué no anteponer / agregar una marca de tiempo a la cadena aleatoria? :)
Erenor Paz
46

Dependiendo de su aplicación (quería generar contraseñas), podría usar

$string = base64_encode(openssl_random_pseudo_bytes(30));

Al ser base64, pueden contener =o -los caracteres solicitados. Puede generar una cadena más larga, luego filtrarla y recortarla para eliminarlas.

openssl_random_pseudo_bytesparece ser la forma recomendada de generar un número aleatorio adecuado en php. ¿ randPor qué no usa /dev/random? No lo sé.

rjmunro
fuente
2
rand no usa / dev / urandom porque solo está disponible en entornos similares a posix y no es portátil.
MacroMan
3
@MacroMan Pero openssl_random_pseudo_bytes() es portátil.
Ja͢ck
Si desea eliminar los caracteres base64 adicionales, intente esto: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley
3
Esto no está mal, pero recomendaría precaución en cómo descartar los caracteres no deseados. Consulte esta solicitud de extracción en el servidor OAuth2 de la liga PHP , por ejemplo.
Scott Arciszewski
Esta es una de las mejores respuestas. Lástima que no tenga más apoyo. Sin embargo, recomendaría editar su respuesta para un mejor manejo de los caracteres no deseados.
jcuenod
28

Aquí hay una línea simple que genera una verdadera cadena aleatoria sin ningún ciclo de secuencia de comandos o uso de bibliotecas OpenSSL.

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

Desglosarlo para que los parámetros estén 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);

Este método funciona repitiendo aleatoriamente la lista de caracteres, luego baraja la cadena combinada y devuelve el número de caracteres especificado.

Puede aleatorizar aún más esto, aleatorizando la longitud de la cadena devuelta, reemplazándola $chrRandomLengthpor mt_rand(8, 15)(para una cadena aleatoria de entre 8 y 15 caracteres).

Kraang Prime
fuente
lamento decirlo, pero cuando un personaje se selecciona, su probabilidad de que ocurra nuevamente no es tan alta como la de los otros personajes que aún permanecen en el grupo. no hay aleatoriedad verdadera aquí ...
The Surrican
@TheSurrican: sería incorrecto en esa declaración. Todos los personajes tienen la misma probabilidad usando este algoritmo, y por lo tanto es verdaderamente aleatorio. Esto se garantiza repitiendo la cadena chrList $ chrRepeatMax, y la magia realmente ocurre en str_shuffle que determina la aleatoriedad.
Kraang Prime
Todos los caracteres aparecerían solo una vez y es muy propenso a la suposición de
fuerza bruta
@venimus Eso es incorrecto. La cadena de caracteres se duplica para tantos caracteres como desee (vea $chrRepeatMaxy $chrRepeatMin), por lo que una cadena de 10 caracteres podría (improbable, pero posible) ser "aaaaaaaaaa".
Kraang Prime
@SanuelJackson Lo siento, comenté mal. He puesto el comentario en la respuesta incorrecta. ¡Tienes razón! En realidad usé tu "truco", pero no usé mt_rand, porque es inútil en mi humilde opinión. No se suma a la entropía. Acabo de usar const con la longitud máxima.
venimus
25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Tada!

Davor
fuente
Tenga en cuenta que sha1dará como resultado un límite de 40 caracteres y siempre caracteres en minúsculas.
fyrye
3
Las cadenas sha1 no son aleatorias, ciertos caracteres aparecerán con más frecuencia que otros. No sería prudente usar esto en casos en los que realmente desee aleatoriedad como para las contraseñas.
Kit Sunde
1
@ KitSunde: sí, sha no es aleatorio, rand () es aleatorio. Y sha está perfectamente bien para lo que se necesita aquí. OP no necesita un nivel criptográfico de aleatoriedad.
Davor
@Davor rant()ser aleatorio no importa cuando sha no está distribuido de manera uniforme. Si selecciona aleatoriamente de una distribución desigual, obtendrá exactamente la misma distribución desigual. No estoy resaltando la aleatoriedad del "nivel de cifrado", si ese fuera el caso, tampoco deberías estar usando rand(). Se requiere un esfuerzo mínimo para obtener una distribución uniforme, como en la respuesta aceptada, y es tan aleatorio como rand (), que es razonable.
Kit Sunde
@ KitSunde: literalmente no hay diferencia al final. Esa es exactamente la definición de sobreingeniería y chapado en oro.
Davor
24

Una mejor manera de implementar esta función es:

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_randes más aleatorio de acuerdo con esto y esto en PHP 7. La randfunción es un alias de mt_rand.

Rathienth Baskaran
fuente
1
Precaución: mt_randno genera valores criptográficamente seguros. Para eso deberías usar PHP7's random_into random_bytes.
jchook
18

$randstringen el ámbito de la función no es lo mismo que el ámbito donde lo llama. Debe asignar el valor de retorno a una variable.

$randstring = RandomString();
echo $randstring;

O simplemente haga eco directamente del valor de retorno:

echo RandomString();

Además, en su función tiene un pequeño error. Dentro del ciclo for, debe usarlo .=para que cada carácter se agregue a la cadena. Al usarlo, =lo sobrescribe con cada nuevo carácter en lugar de agregarlo.

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

Primero, define el alfabeto que desea usar:

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

Luego, use openssl_random_pseudo_bytes()para generar datos aleatorios adecuados:

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

Finalmente, utiliza estos datos aleatorios para crear la contraseña. Debido a que cada carácter $randompuede ser chr(0)hasta chr(255), el código usa el resto después de la división de su valor ordinal $alphabet_lengthpara asegurarse de que solo se seleccionen los caracteres del alfabeto (tenga en cuenta que al hacerlo sesga la aleatoriedad):

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

Alternativamente, y en general mejor, es usar RandomLib y SecurityLib :

use SecurityLib\Strength;

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

$password = $generator->generateString(12, $alphabet);
Ja͢ck
fuente
El uso del operador de módulo %producirá una salida sesgada. Sin embargo, fuerte +1 para RandomLib. No reinventes la rueda.
Scott Arciszewski
1
Sí, la nueva función random_int () es agradable: D
Ja͢ck
11

Métodos cortos.

Estos son algunos de los métodos más cortos para generar la cadena aleatoria.

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

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

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

He probado el rendimiento de las funciones más populares allí, el tiempo necesario para generar 1'000'000 cadenas de 32 símbolos en mi caja es:

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

Tenga en cuenta que no es importante cuánto tiempo fue realmente, sino cuál es más lento y cuál es más rápido, por lo que puede seleccionar de acuerdo con sus requisitos, incluida la preparación de criptografía, etc.

Se agregó substr () alrededor de MD5 en aras de la precisión si necesita una cadena que sea más corta que 32 símbolos.

En aras de la respuesta: la cadena no se concatenó sino que se sobrescribió y el resultado de la función no se almacenó.

Putnik
fuente
Creo que esa es la mejor respuesta. ¡Gracias!
NSukonny
10

PHP 7+ Genera bytes aleatorios criptográficamente seguros utilizando la función random_bytes .

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

Salida posible

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ Genera bytes pseudoaleatorios usando la función openssl_random_pseudo_bytes .

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

Salida posible

e2d1254506fbb6cd842cd640333214ad


El mejor caso de uso podría 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();

Salida posible

ba8cc342bdf91143

Madan Sapkota
fuente
Esto no generará una cadena con la longitud dada
Timberman
@Timberman generará la longitud exacta ahora.
Madan Sapkota
9

Una forma muy rápida es hacer algo como:

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

Esto generará una cadena aleatoria con la longitud de 10 caracteres. Por supuesto, algunos podrían decir que es un poco más pesado en el lado de la computación, pero hoy en día los procesadores están optimizados para ejecutar el algoritmo md5 o sha256 muy rápidamente. Y, por supuesto, si la rand()función devuelve el mismo valor, el resultado será el mismo, con una probabilidad de 1/32767 de ser el mismo. Si la seguridad es el problema, simplemente cambie rand()amt_rand()

Akatosh
fuente
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;
}
Руслан Ибрагимов
fuente
44
Esto no es portátil; Si intenta ejecutar esto en cualquier entorno que no sea posix, causará un error fatal.
Bryan Agee
7

Este fue tomado de fuentes administrativas :

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

Adminer , herramienta de gestión de bases de datos escrita en PHP.

userlond
fuente
6

Función auxiliar del 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
fuente
44
"No debe considerarse suficiente para la criptografía, etc." Esto debe enfatizarse fuertemente.
Scott Arciszewski
4

La versión editada de la función funciona bien, pero solo encontré un problema: usó el carácter incorrecto para encerrar $ caracteres, por lo que el carácter 'a veces es parte de la cadena aleatoria que se genera.

Para arreglar esto, cambie:

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

a:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

De esta forma, solo se utilizan los caracteres encerrados, y el carácter 'nunca será parte de la cadena aleatoria que se genera.

bmcswee
fuente
4

Otra línea única, que genera una cadena aleatoria de 10 caracteres con letras y números. Creará una matriz con range(ajuste el segundo parámetro para establecer el tamaño), recorre esta matriz y asigna un carácter ASCII aleatorio (rango 0-9 o az), luego implosiona la matriz para obtener una cadena.

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

Nota: esto solo funciona en PHP 5.3 y posterior

kasimir
fuente
Finalmente, una solución verdaderamente aleatoria, no un hash hinchado de un entero aleatorio de 32 bits o una cadena aleatoria ...
The Surrican
solo hay un problema: es probable que los números aparezcan como caracteres, lo cual no es tan aleatorio como me encantaría tenerlo. anyaway +1 para la mejor solución en esta página. ajustar eso y es perfecto.
The Surrican
ajustar ... como este? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth
4

Un trazador de líneas.

Es rápido para cuerdas enormes con cierta singularidad.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
Jacob Smith
fuente
md5(rand())Es una forma terriblemente insegura de generar un número aleatorio.
Scott Arciszewski
1
Una secuencia con X longitud y cierta singularidad es la intención. La verdadera aleatoriedad no es la intención.
Jacob Smith
3

Me gustó el último comentario que usó openssl_random_pseudo_bytes, pero no fue una solución para mí, ya que todavía tenía que eliminar los caracteres que no quería, y no pude obtener una cadena de longitud establecida. Aquí está mi solución ...

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
fuente
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
fuente
3

Aquí está mi solución simple de una línea para generar una contraseña aleatoria amigable, excluyendo los caracteres que se parecen, como "1" y "l", "O" y "0", etc. Aquí hay 5 caracteres, pero puede fácilmente cambiarlo por supuesto:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);
rAthus
fuente
Esto es perfecto para crear cadenas de identificación aleatorias para llamar más tarde en jquery. IDK si es una buena práctica, pero esto me ayudó mucho, sin usar un por como la respuesta aceptada ...
Rodrigo Zuluaga
3

Aquí hay otra solución.

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

PD. Estoy usando PHP 7.2 en Ubuntu.

Umair Khan
fuente
2

Otra forma de generar una cadena aleatoria en PHP es:

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
fuente
2

Así es como lo estoy haciendo para obtener una verdadera clave aleatoria única:

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

Puede usar time () ya que es una marca de tiempo Unix y siempre es única en comparación con otras aleatorias mencionadas anteriormente. Luego puede generar la suma md5 de eso y tomar la longitud deseada que necesita del MD5 generado cadena . En este caso, estoy usando 10 caracteres, y podría usar una cadena más larga si quisiera hacerla más única.

Espero que esto ayude.

Sherpa
fuente
2
Por supuesto, time()está lejos de ser único: devolverá el mismo valor una y otra vez hasta que finalice el segundo actual. Lo que realmente proporciona algo de aleatoriedad aquí es que str_shuffle()el resto del código solo reduce la muestra para elegir caracteres.
Álvaro González
1
entonces, lo que básicamente estás haciendo es barajar un número entero de 32 bits. no hay mucha entropía aquí ...
The Surrican
2
Un atacante puede adivinar el valor devuelto por time()(es solo una marca de tiempo), es una fuente débil de aleatoriedad.
AL
2

One-liner parametrizado usando solo funciones nativas de PHP , trabajando desde 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))))))
usuario10099
fuente