Generatore di stringhe casuali PHP


814

Sto cercando di creare una stringa randomizzata in PHP e non ottengo assolutamente alcun output con questo:

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

    RandomString();
    echo $randstring;

Che cosa sto facendo di sbagliato?


241
La mia soluzione a una riga per generare una stringa breve è substr (md5 (rand ()), 0, 7); buona fortuna ...
tasmaniski,

5
@tasmaniski .. La tua soluzione è ok .. Ma è meno randomizzata! Nel tuo esempio il numero di stringhe casuali che possono essere generate è limitato dalla dimensione dell'intero. (2 ^ 32) al massimo .. Nel caso dell'altra soluzione, è possibile generare (62 ^ 8) .. Nel caso, voglio stringhe più grandi, quindi il numero di stringhe distinte rimane al massimo 2 ^ 32, ma nel altra soluzione aumenta a (62 ^ n) ..
Manu

9
Hai dimenticato di aggiungere ogni nuovo carattere generato alla stringa. Lo stai sovrascrivendo così com'è. Dovrebbe essere $ randstring. = $ Caratteri ..
Spock

3
@CaptainLightning Puoi per favore scambiare la risposta accettata con una delle più sicure? :)
Scott Arciszewski,

2
strlen($characters)=> strlen($characters) - 1- la lunghezza della stringa inizia con 1
Zippp

Risposte:


1394

Per rispondere specificamente a questa domanda, due problemi:

  1. $randstring non rientra nell'ambito quando lo si fa eco.
  2. I personaggi non vengono concatenati insieme nel loop.

Ecco uno snippet di codice con le correzioni:

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

Emetti la stringa casuale con la chiamata seguente:

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

Si noti che ciò genera stringhe casuali prevedibili. Se vuoi creare token sicuri, vedi questa risposta .


34
@FranciscoPresencia, è meglio "sprecare" una variabile aggiuntiva al momento di chiamare un metodo nella condizione di confronto di un ciclo.
Rico Sonntag,

200
Tutto quel lavoro, perché non solo qualcosa del genere substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH

4
Grazie per il codice, ma per favore cambia rand()in mt_rand(). Ho usato il tuo metodo e ho avuto un sacco di collisioni con i nomi.
Nate,

5
@FranciscoPresencia hai idea di quanto sia terribilmente inefficiente? Stai controllando la lunghezza di una stringa due volte per iterazione! Lo strlen all'interno del loop dovrebbe essere memorizzato nella cache in una variabile prima di entrare anche nel loop.
Developerbmw

4
Questa non è una buona soluzione. Le stringhe che questo genera saranno prevedibili. :(
Scott Arciszewski,

370

Nota: str_shuffle()utilizza internamente rand(), che non è adatto a scopi di crittografia (ad es. Generazione di password casuali). Si desidera invece un generatore di numeri casuali sicuro . Inoltre, non consente ai personaggi di ripetere.

Un altro modo.

AGGIORNATO (ora questo genera qualsiasi lunghezza di stringa):

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

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

Questo è tutto. :)


64
+1 per la risposta più breve :). Ma non è la risposta migliore per ogni caso d'uso. Questo codice genererà stringhe in cui ogni personaggio non apparirà più di una volta (rendendolo così più debole per gli attacchi di forza bruta) e non produrrà più di 62 caratteri.
David,

17
Non farlo, è estremamente debole. Più a lungo crei la tua stringa casuale, più debole sarà.
Abhi Beckert,

23
Potrebbe essere debole, ma è semplice e veloce. A seconda del caso d'uso, questo va bene - l'ho usato perché non avevo bisogno di sicurezza o forza; solo uno shuffle a fuoco rapido. Sto scrivendo un unit test e questo mi dà un input opportunamente casuale con cui testare.
DSC

23
@FranciscoPresencia il motivo per cui non è sicuro è perché non utilizza mai lo stesso carattere due volte. Questo lo rende un terribile generatore di password. Per favore, tutti smettono di votare questo, è totalmente insicuro, non deve mai essere usato. Man mano che la password si allunga, il numero di caratteri che devi testare in modo bruto si accorcia perché non ti preoccupi di testare alcun personaggio usato in precedenza.
Abhi Beckert,

8
@FranciscoPresencia: sostengo i tuoi commenti sull'evitare di utilizzare questo per password casuali. Tuttavia, non sono d'accordo sul fatto che questa risposta non dovrebbe essere più positiva. Ho scelto questa opzione in più poiché è un'efficace soluzione su una riga per generare stringhe casuali (l'argomento originale di questa domanda).
bwright,

331

Ci sono molte risposte a questa domanda, ma nessuna di esse sfrutta un generatore di numeri pseudo-casuali crittograficamente sicuro (CSPRNG).

La risposta semplice, sicura e corretta è usare RandomLib e non reinventare la ruota.

Per quelli di voi che insistono nell'inventare la propria soluzione, PHP 7.0.0 fornirà random_int()a tale scopo; se sei ancora su PHP 5.x, abbiamo scritto un polyfill per PHP 5 inrandom_int() modo da poter utilizzare la nuova API anche prima di eseguire l'aggiornamento a PHP 7.

Generare in modo sicuro numeri interi casuali in PHP non è un compito banale. È sempre necessario verificare con gli esperti di crittografia StackExchange residenti prima di distribuire un algoritmo di produzione domestica.

Con un generatore di numeri interi sicuro installato, generare una stringa casuale con un CSPRNG è una passeggiata nel parco.

Creazione di una stringa sicura e casuale

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

Utilizzo :

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

Demo : https://3v4l.org/IMJGF (Ignora gli errori PHP 5; ha bisogno di random_compat)


3
All'inizio della funzione aggiungi $keyspace = str_shuffle($keyspace );per maggiore sicurezza
Jevgenij Dmitrijev

13
Cosa intendi con "per maggiore sicurezza"? Stiamo già utilizzando un generatore di numeri casuali sicuro.
Scott Arciszewski,

5
@JGEstiot La creazione di stringhe casualmente sicure richiede casualità crittograficamente sicura. Qualcuno che cerca "come generare stringhe casuali in PHP" è meglio servito da una risposta sicura che da una risposta non sicura.
Scott Arciszewski,

1
@ Scott Arciszewski Non è necessario creare stringhe crittografiche casuali ogni volta che si creano stringhe casuali. La domanda era sulla creazione di stringhe casuali e questo non ha nulla a che fare con la sicurezza. Hai presupposto che la stringa verrà utilizzata in un contesto sensibile alla sicurezza e aggiungi un livello di complessità che si allontana dal nocciolo della domanda.
JG Estiot

45
L'utilizzo random_int()anziché rand()o mt_rand()non aggiunge complessità per lo sviluppatore. Allo stesso tempo, offre loro una maggiore sicurezza. Le persone che vengono su StackOverflow alla ricerca di soluzioni rapide potrebbero non sapere se la cosa che stanno costruendo deve essere sicura o meno. Se diamo loro risposte sicure per impostazione predefinita, creano un Internet più sicuro anche se, dal loro punto di vista, è totalmente accidentale. Perché ti opporti a questo obiettivo è un mistero per me.
Scott Arciszewski,

156

Questo crea una stringa esadecimale lunga 20 caratteri:

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

In 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

Si noti che openssl_random_pseudo_bytes()non è stato utilizzato un algoritmo crittograficamente potente fino a php 5.6. Bug correlato: bugs.php.net/bug.php?id=70014
acidtv

Si noti inoltre che la stringa più piccola che può essere prodotta è di lunghezza 2. Se si passa una lunghezza di byte pari o inferiore a 1, openssl_random_pseudo_bytes()non verrà restituito nulla. Inoltre, tieni presente che quando lo usi bin2hex(openssl_random_pseudo_bytes($length / 2))poiché lavori con numeri interi, rimuoverà automaticamente il modulo e utilizzerà il multiplo più basso successivo di 2. Quindi, $length = 19produrrà una stringa di lunghezza 18.
Nathan F.

Proposta di utilizzarlo come contenuto del file che può essere aperto tramite fgets($fp, 1024)ogni editor di file che presenta problemi con righe molto lunghe: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }impostare $splitsu nullse deve restituire una riga . Con ciò puoi usarlo per entrambi i casi.
mgutt

Mi piace molto la soluzione random_bytes per PHP 7, ma se hai bisogno che la stringa sia un certo numero di caratteri qualcosa di simile funzionerebbe? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programmatore,

Questa è senza dubbio la soluzione migliore. Occupa pochissimo spazio ed è super facile da capire.
Matthew Campbell,

92

@tasmaniski: la tua risposta ha funzionato per me. Ho avuto lo stesso problema e lo consiglierei a coloro che sono sempre alla ricerca della stessa risposta. Eccolo da @tasmaniski:

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

Ecco un video di YouTube che ci mostra come creare un numero casuale


6
se la tua stringa si basa solo su un numero intero casuale, perché non usare solo il numero intero casuale? il pagliaio non si approfondisce più tagliandolo ... e tagliando l'hash di te in realtà sminuisce la piccola entropia con cui hai dovuto iniziare.
The Surrican,

4
Tieni presente md5che comporterà un limite di 30 caratteri e sempre caratteri minuscoli.
Fyrye,

3
Inoltre, rand () non dovrebbe essere usato per la crittografia. Se stai cercando di generare una stringa crittograficamente valida , usa openssl_random_pseudo_bytes .
Mattkgross,

md5(rand())offre solo 2 ^ 32 possibili valori. Ciò significa che dopo, in media, 2 ^ 16 stringhe casuali ti aspetteresti di ripetere.
Scott Arciszewski,

2
Beh.. scommetto che l'OP non sta parlando di "stringhe sicure in modo casuale". Questa soluzione è compatta, facile e carina da ricordare, per i casi d'uso giusti . E, se è necessario occuparsi delle possibili collisioni, perché non anteporre / aggiungere un timestamp alla stringa casuale? :)
Erenor Paz,

46

A seconda della tua applicazione (volevo generare password), potresti usarla

$string = base64_encode(openssl_random_pseudo_bytes(30));

Essendo base64, possono contenere =o -anche i caratteri richiesti. È possibile generare una stringa più lunga, quindi filtrarla e tagliarla per rimuoverla.

openssl_random_pseudo_bytessembra essere il modo consigliato per generare un numero casuale corretto in php. Perché randnon lo uso /dev/random, non lo so.


2
rand non usa / dev / urandom perché è disponibile solo in ambienti come posix e non è portatile.
MacroMan

3
@MacroMan But openssl_random_pseudo_bytes() è portatile.
Ja͢ck,

Se vuoi eliminare i caratteri extra base64, prova questo: gist.github.com/zyphlar/7217f566fc83a9633959
willbradley,

3
Questo non è sbagliato, ma consiglierei cautela su come scartare i personaggi indesiderati. Vedi questa richiesta pull sul server OAuth2 della lega PHP , per esempio.
Scott Arciszewski,

Questa è una delle migliori risposte. Peccato che non abbia più supporto. Consiglio comunque di modificare la tua risposta per una migliore gestione dei personaggi indesiderati.
jcuenod,

28

Ecco un semplice one-liner che genera una vera stringa casuale senza alcun ciclo a livello di script o utilizzo delle librerie OpenSSL.

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

Per scomporlo in modo che i parametri siano chiari

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

Questo metodo funziona ripetendo casualmente l'elenco dei caratteri, quindi mescola la stringa combinata e restituisce il numero di caratteri specificato.

Puoi randomizzare ulteriormente questo, randomizzando la lunghezza della stringa restituita, sostituendola $chrRandomLengthcon mt_rand(8, 15)(per una stringa casuale compresa tra 8 e 15 caratteri).


mi dispiace dirlo, ma quando un personaggio viene selezionato la sua probabilità di ripetersi non è alta come gli altri personaggi che rimangono nel pool. nessuna vera casualità qui ...
The Surrican,

@TheSurrican - Sarebbe errato in quella dichiarazione. Tutti i personaggi hanno la stessa probabilità usando questo algoritmo, e quindi è veramente casuale. Ciò è garantito ripetendo la stringa chrList $ chrRepeatMax, e la magia si verifica davvero in str_shuffle che determina la casualità.
Kraang Prime,

Tutti i caratteri appariranno solo una volta ed è molto incline a indovinare bruteforce
venimus,

@venimus Quello è errato. La stringa di caratteri è duplicata per tutti i caratteri che vuoi (vedi $chrRepeatMaxe $chrRepeatMin) - quindi una stringa di 10 caratteri, potrebbe (improbabile, ma possibile), essere "aaaaaaaaaa".
Kraang Prime,

@SanuelJackson Mi dispiace, ho perso un commento. Ho inserito il commento sulla risposta sbagliata. Hai ragione! In realtà ho usato il tuo "trucco", ma non ho usato mt_rand, perché è IMHO inutile. Non si aggiunge all'entropia. Usato solo const con la lunghezza massima.
venimus,

25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Tada!


Tieni presente sha1che comporterà un limite di 40 caratteri e sempre caratteri minuscoli.
fyrye,

3
le stringhe sha1 non sono casuali, alcuni caratteri si verificano più frequentemente di altri. Non sarebbe saggio utilizzarlo nei casi in cui desideri davvero la casualità come per le password.
Kit Sunde,

1
@KitSunde - sì, sha non è casuale, rand () è casuale. E sha sta perfettamente bene per ciò che è necessario qui. OP non ha bisogno del livello criptico di casualità.
Assapora il

@ Godere di rant()essere casuali non importa quando sha non è distribuito uniformemente. Se si seleziona casualmente da una distribuzione irregolare, si ottiene esattamente la stessa distribuzione irregolare. Non è la casualità di "livello crittografico" che sto evidenziando, se così fosse non dovresti usare rand()neanche. Ci vuole uno sforzo minimo per ottenere una distribuzione uniforme come nella risposta accettata ed è casuale come rand () è ragionevolmente così.
Kit Sunde,

@KitSunde - alla fine non fa letteralmente alcuna differenza. Questa è esattamente la definizione di sovraingegneria e doratura.
Assapora il

24

Un modo migliore per implementare questa funzione è:

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è più casuale secondo questo e questo in PHP 7. La randfunzione è un alias di mt_rand.


1
Attenzione: mt_randnon genera valori crittograficamente sicuri. Per questo dovresti usare PHP7 random_into random_bytes.
jchook,

18

$randstringnell'ambito della funzione non è uguale all'ambito in cui viene chiamato. Devi assegnare il valore restituito a una variabile.

$randstring = RandomString();
echo $randstring;

O rispondi direttamente al valore di ritorno:

echo RandomString();

Inoltre, nella tua funzione hai un piccolo errore. All'interno del ciclo for, è necessario utilizzare in .=modo che ogni carattere venga aggiunto alla stringa. Usandolo =stai sovrascrivendolo con ogni nuovo personaggio invece di aggiungerlo.

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

14

Innanzitutto, definisci l'alfabeto che desideri utilizzare:

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

Quindi, utilizzare openssl_random_pseudo_bytes()per generare dati casuali corretti:

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

Infine, usi questi dati casuali per creare la password. Poiché ogni carattere in $randompuò essere chr(0)fino a chr(255), il codice utilizza il resto dopo la divisione del suo valore ordinale con $alphabet_lengthper assicurarsi che vengano scelti solo i caratteri dell'alfabeto (notare che in questo modo si distorce la casualità):

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

In alternativa, e generalmente meglio, è usare RandomLib e SecurityLib :

use SecurityLib\Strength;

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

$password = $generator->generateString(12, $alphabet);

L'uso dell'operatore modulo %produrrà un output distorto. Tuttavia, +1 forte per RandomLib. Non reinventare la ruota.
Scott Arciszewski,

1
Sì, la nuova funzione random_int () è carina: D
Ja͢ck

11

Metodi brevi ..

Ecco alcuni dei metodi più brevi per generare la stringa casuale

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

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

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

10

Ho testato le prestazioni delle funzioni più popolari lì, il tempo necessario per generare 1'000'000 stringhe di 32 simboli sulla mia scatola è:

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

Si noti che non è importante quanto tempo è stato, ma quale è più lento e quale è più veloce, quindi è possibile selezionare in base alle proprie esigenze, tra cui la predisposizione alla crittografia, ecc.

substr () attorno a MD5 è stato aggiunto per maggiore precisione se è necessaria una stringa più corta di 32 simboli.

Per ragioni di risposta: la stringa non è stata concatenata ma sovrascritta e il risultato della funzione non è stato memorizzato.


Penso, quella migliore risposta. Grazie!
NSukonny

10

PHP 7+ Genera byte casuali crittograficamente sicuri usando la funzione random_bytes .

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

Uscita possibile

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ Genera byte pseudo-casuali usando la funzione openssl_random_pseudo_bytes .

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

Uscita possibile

e2d1254506fbb6cd842cd640333214ad


Il miglior caso d'uso potrebbe essere

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

Uscita possibile

ba8cc342bdf91143


Questo non genererà una stringa con la lunghezza data
Timberman

@Timberman ora genererà la lunghezza esatta.
Madan Sapkota,

9

Un modo molto veloce è fare qualcosa del tipo:

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

Questo genererà una stringa casuale con la lunghezza di 10 caratteri. Naturalmente, alcuni potrebbero dire che è un po 'più pesante dal punto di vista del calcolo, ma oggigiorno i processori sono ottimizzati per eseguire l'algoritmo md5 o sha256 molto rapidamente. E, naturalmente, se la rand()funzione restituisce lo stesso valore, il risultato sarà lo stesso, con una probabilità 1/32767 di essere lo stesso. Se la sicurezza è il problema, basta passare rand()amt_rand()


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

4
Questo non è portatile; se si tenta di eseguirlo in qualsiasi ambiente non posix, si verificherà un errore irreversibile.
Bryan Agee,

7

Questo è stato preso da fonti di amministrazione :

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

Amministratore , strumento di gestione del database scritto in PHP.


6

Funzione di supporto dal 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);
}

4
"Non dovrebbe essere considerato sufficiente per la crittografia, ecc." Questo dovrebbe essere fortemente enfatizzato.
Scott Arciszewski,


4

La versione modificata della funzione funziona bene, ma ho riscontrato solo un problema: hai usato il carattere sbagliato per racchiudere $ caratteri, quindi il carattere a volte fa parte della stringa casuale che viene generata.

Per risolvere questo problema, modifica:

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

per:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

In questo modo vengono utilizzati solo i caratteri racchiusi e il carattere 'non farà mai parte della stringa casuale generata.


4

Un altro one-liner, che genera una stringa casuale di 10 caratteri con lettere e numeri. Creerà un array con range(regola il secondo parametro per impostare la dimensione), passa su questo array e assegna un carattere ASCII casuale (intervallo 0-9 o az), quindi implode l'array per ottenere una stringa.

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

Nota: funziona solo in PHP 5.3 e versioni successive


finalmente una soluzione veramente casuale, non un hash gonfio di un intero casuale a 32 bit o una stringa mescolata ...
The Surrican,

c'è solo un problema: i numeri hanno la probabilità che si verifichino come personaggi, che non è così casuale come mi piacerebbe averlo. comunque +1 per la migliore soluzione in questa pagina. ottimizzalo ed è perfetto.
The Surrican,

modificare ... in questo modo? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth,

4

Una fodera

È veloce per stringhe enormi con una certa unicità.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}

md5(rand())è un modo orribilmente insicuro per generare un numero casuale.
Scott Arciszewski,

1
l'intento è una stringa con lunghezza X e unicità. la vera casualità non è l'intento.
Jacob Smith,


3

Mi è piaciuto l'ultimo commento che ha usato openssl_random_pseudo_bytes, ma non è stata una soluzione per me in quanto dovevo ancora rimuovere i caratteri che non volevo e non ero in grado di ottenere una stringa di lunghezza impostata. Ecco la mia soluzione ...

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

3
function randomString($length = 5) {
    return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}

3

Ecco la mia semplice soluzione a una riga per generare una password casuale facile da usare, esclusi i caratteri che assomigliano a "1" e "l", "O" e "0", ecc ... qui ci sono 5 caratteri ma puoi facilmente cambiarlo ovviamente:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);

Questo è perfetto per creare stringhe di ID casuali da chiamare in seguito in jquery. IDK se è una buona pratica, ma questo mi ha aiutato molto, senza usare un come la risposta accettata ...
Rodrigo Zuluaga,

3

Ecco un'altra soluzione.

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. Sto usando PHP 7.2 su Ubuntu.


2

Un altro modo per generare una stringa casuale in 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);

2

Ecco come lo sto facendo per ottenere una vera chiave casuale unica:

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

Puoi usare time () poiché è un timestamp Unix ed è sempre unico rispetto ad altri casuali sopra menzionati. È quindi possibile generare il md5sum di quello e prendere la lunghezza desiderata necessaria dalla stringa MD5 generata . In questo caso sto usando 10 caratteri e potrei usare una stringa più lunga se volessi renderlo più unico.

Spero che questo possa essere d'aiuto.


2
Certo, time()è tutt'altro che unico: restituirà lo stesso valore ancora e ancora fino alla fine del secondo corrente. Ciò che offre davvero un po 'di casualità qui è: str_shuffle()il resto del codice riduce solo il campione da cui selezionare i caratteri.
Álvaro González,

1
quindi quello che stai sostanzialmente facendo è mescolare un intero a 32 bit. qui non c'è molta entropia ...
The Surrican,

2
Un attaccante può indovinare il valore restituito da time()(è solo un timestamp), è una debole fonte di casualità.
AL

2

One-liner parametrizzato che utilizza solo funzioni native PHP , funzionante da 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))))))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.