PHP Zufallszeichenfolgengenerator

814

Ich versuche, eine zufällige Zeichenfolge in PHP zu erstellen, und ich erhalte damit absolut keine Ausgabe:

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

    RandomString();
    echo $randstring;

Was mache ich falsch?

Captain Lightning
quelle
241
Meine einzeilige Lösung zum Generieren eines kurzen Strings ist substr (md5 (rand ()), 0, 7);
Viel
5
@ Tasmaniski .. Ihre Lösung ist in Ordnung .. Aber es ist weniger zufällig! In Ihrem Beispiel ist die Anzahl der zufälligen Zeichenfolgen, die generiert werden können, durch die Größe der Ganzzahl begrenzt. (2 ^ 32) am Maximum. Bei der anderen Lösung können Sie (62 ^ 8) generieren. Wenn ich größere Zeichenfolgen möchte, bleibt die Anzahl der unterschiedlichen Zeichenfolgen bei maximal 2 ^ 32, aber in der andere Lösung erhöht es auf (62 ^ n) ..
Manu
9
Sie haben vergessen, jedes neu generierte Zeichen zur Zeichenfolge hinzuzufügen. Sie überschreiben es einfach so wie es ist. Sollte $ randstring sein. = $ Zeichen ..
Spock
3
@CaptainLightning Können Sie bitte die akzeptierte Antwort gegen eine der sichereren austauschen? :)
Scott Arciszewski
2
strlen($characters)=> strlen($characters) - 1- Stringlänge beginnt mit 1
Zippp

Antworten:

1393

Um diese Frage speziell zu beantworten, zwei Probleme:

  1. $randstring ist nicht im Geltungsbereich, wenn Sie es wiederholen.
  2. Die Zeichen werden in der Schleife nicht miteinander verkettet.

Hier ist ein Code-Snippet mit den Korrekturen:

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

Geben Sie die zufällige Zeichenfolge mit dem folgenden Aufruf aus:

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

Bitte beachten Sie, dass dies vorhersehbare zufällige Zeichenfolgen generiert. Wenn Sie sichere Token erstellen möchten, lesen Sie diese Antwort .

Stephen Watkins
quelle
34
@FranciscoPresencia, es ist besser, eine zusätzliche Variable zu "verschwenden", als eine Methode in der Vergleichsbedingung einer Schleife aufzurufen.
Rico Sonntag
200
All diese Arbeit, warum nicht einfach so etwas substr(str_shuffle(MD5(microtime())), 0, 10);?
SpYk3HH
4
Danke für den Code, aber bitte wechseln Sie rand()zu mt_rand(). Ich habe Ihre Methode angewendet und eine Menge Kollisionen mit Namen erlebt .
Nate
5
@FranciscoPresencia Hast du eine Idee, wie schrecklich ineffizient das ist? Sie überprüfen die Länge eines Strings zweimal pro Iteration! Die Strlen innerhalb der Schleife sollten vor dem Betreten der Schleife in einer Variablen zwischengespeichert werden.
Developerbmw
4
Dies ist keine gute Lösung. Die dadurch erzeugten Zeichenfolgen sind vorhersehbar. :(
Scott Arciszewski
370

Hinweis: Wird str_shuffle()intern verwendet rand(), was für Kryptografiezwecke ungeeignet ist (z. B. Generieren von zufälligen Kennwörtern). Sie möchten stattdessen einen sicheren Zufallszahlengenerator . Es erlaubt auch nicht, dass Zeichen wiederholt werden.

Noch ein Weg.

AKTUALISIERT (dies erzeugt jetzt eine beliebige Länge der Zeichenfolge):

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

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

Das ist es. :) :)

A. Cheshirov
quelle
64
+1 für die kürzeste Antwort :). Aber nicht die beste Antwort für jeden Anwendungsfall. Dieser Code gibt Zeichenfolgen aus, bei denen jedes Zeichen nicht mehr als einmal angezeigt wird (wodurch es für Brute-Force-Angriffe schwächer wird), und gibt nichts länger als 62 Zeichen aus.
David
17
Tun Sie dies nicht, es ist extrem schwach. Je länger Sie Ihre zufällige Zeichenfolge erstellen, desto schwächer wird sie.
Abhi Beckert
23
Schwach mag es sein, aber es ist schnell und einfach. Je nach Anwendungsfall ist dies in Ordnung - ich habe es verwendet, weil ich keine Sicherheit oder Stärke brauchte. nur ein Schnellfeuer-Shuffle. Ich schreibe einen Komponententest, und dies gibt mir eine entsprechend zufällige Eingabe zum Testen.
DEZA
23
@FranciscoPresencia Der Grund, warum es nicht sicher ist, ist, dass es nie zweimal dasselbe Zeichen verwendet. Das macht es zu einem schrecklichen Passwortgenerator. Bitte alle hören auf, dies abzustimmen, es ist völlig unsicher und darf niemals verwendet werden. Je länger das Passwort wird, desto kürzer wird die Anzahl der Zeichen, die Sie mit Brute Force testen müssen, da Sie sich nicht die Mühe machen, zuvor verwendete Zeichen zu testen.
Abhi Beckert
8
@FranciscoPresencia: Ich unterstütze Ihre Kommentare zur Vermeidung der Verwendung für zufällige Passwörter. Ich bin jedoch nicht der Meinung, dass diese Antwort nicht plus-one'd sein sollte. Ich habe diese Option mit einem Plus versehen, da es sich um eine effektive einzeilige Lösung zum Generieren von zufälligen Zeichenfolgen handelt (das ursprüngliche Thema dieser Frage).
Bwright
331

Es gibt viele Antworten auf diese Frage, aber keine davon nutzt einen kryptografisch sicheren Pseudozufallszahlengenerator (CSPRNG).

Die einfache, sichere und richtige Antwort ist, RandomLib zu verwenden und das Rad nicht neu zu erfinden.

Für diejenigen unter Ihnen, die darauf bestehen, Ihre eigene Lösung zu erfinden, bietet PHP 7.0.0 random_int()diesen Zweck. Wenn Sie noch mit PHP 5.x arbeiten, haben wir eine PHP 5-Polyfüllung für geschrieben,random_int() damit Sie die neue API verwenden können, noch bevor Sie auf PHP 7 aktualisieren.

Das sichere Generieren zufälliger Ganzzahlen in PHP ist keine triviale Aufgabe. Sie sollten sich immer an Ihre ansässigen StackExchange-Kryptografieexperten wenden, bevor Sie einen selbst entwickelten Algorithmus in der Produktion bereitstellen.

Mit einem sicheren Integer-Generator ist das Generieren einer zufälligen Zeichenfolge mit einem CSPRNG ein Spaziergang im Park.

Erstellen einer sicheren, zufälligen Zeichenfolge

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

Verwendung :

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

Demo : https://3v4l.org/IMJGF (Ignoriere die PHP 5-Fehler; es wird random_compat benötigt)

Scott Arciszewski
quelle
3
Zu Beginn der Funktion $keyspace = str_shuffle($keyspace );für mehr Sicherheit hinzufügen
Jevgenij Dmitrijev
13
Was meinst du mit "für mehr Sicherheit"? Wir verwenden bereits einen sicheren Zufallszahlengenerator.
Scott Arciszewski
5
@JGEstiot Das Erstellen sicher zufälliger Zeichenfolgen erfordert eine kryptografisch sichere Zufälligkeit. Jemand, der nach "wie man zufällige Zeichenfolgen in PHP generiert" sucht, wird von einer sicheren Antwort besser bedient als von einer unsicheren Antwort.
Scott Arciszewski
1
@ Scott Arciszewski Sie müssen nicht jedes Mal kryptografisch zufällige Zeichenfolgen erstellen, wenn Sie zufällige Zeichenfolgen erstellen. Die Frage war, ob zufällige Zeichenfolgen erstellt werden sollen, und dies hat nichts mit Sicherheit zu tun. Sie haben angenommen, dass die Zeichenfolge in einem sicherheitsrelevanten Kontext verwendet wird, und Sie fügen eine Komplexitätsebene hinzu, die sich vom Kern der Frage unterscheidet.
JG Estiot
45
Die Verwendung random_int()anstelle von rand()oder mt_rand()fügt dem Entwickler keine Komplexität hinzu. Gleichzeitig gibt es ihnen mehr Sicherheit. Leute, die zu StackOverflow kommen und nach schnellen Lösungen suchen, wissen möglicherweise nicht, ob das, was sie bauen, sicher sein muss oder nicht. Wenn wir ihnen standardmäßig sichere Antworten geben, schaffen sie ein sichereres Internet, auch wenn es aus ihrer Sicht völlig zufällig ist. Warum Sie sich diesem Ziel widersetzen würden, ist mir ein Rätsel.
Scott Arciszewski
156

Dadurch wird eine 20 Zeichen lange hexadezimale Zeichenfolge erstellt:

$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
Rudie
quelle
Bitte beachten Sie, dass openssl_random_pseudo_bytes()bis PHP 5.6 kein kryptografisch starker Algorithmus verwendet wurde. Verwandte Fehler: bugs.php.net/bug.php?id=70014
acidtv
Beachten Sie auch, dass die kleinste Zeichenfolge, die dies machen kann, die Länge 2 hat. Wenn Sie eine Bytelänge von 1 oder weniger an openssl_random_pseudo_bytes()Sie übergeben, erhalten Sie nichts zurück. Beachten bin2hex(openssl_random_pseudo_bytes($length / 2))Sie außerdem, dass bei der Verwendung, da Sie mit Ganzzahlen arbeiten, das Modulo automatisch entfernt wird und das nächstniedrigere Vielfache von 2 verwendet wird. So $length = 19wird eine Zeichenfolge mit der Länge 18 erzeugt.
Nathan F.
Vorschlag, es als Dateiinhalt zu verwenden, der geöffnet werden kann, fgets($fp, 1024)und für jeden Datei-Editor, der Probleme mit sehr langen Zeilen hat: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }Legen Sie fest $split, nullob ein Einzeiler zurückgegeben werden soll. Auf diese Weise können Sie es für beide Fälle verwenden.
mgutt
Ich mag die random_bytes-Lösung für PHP 7 wirklich, aber wenn die Zeichenfolge eine bestimmte Anzahl von Zeichen haben muss, würde so etwas funktionieren? $string = substr(base64_encode(random_bytes($size)), 0, $size);
Programster
Dies ist ohne Zweifel die beste Lösung. Nimmt sehr wenig Platz ein und ist super leicht zu verstehen.
Matthew Campbell
92

@ Tasmaniski: Ihre Antwort hat bei mir funktioniert. Ich hatte das gleiche Problem und würde es denen empfehlen, die jemals nach der gleichen Antwort suchen. Hier ist es von @tasmaniski:

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

Hier ist ein Youtube-Video, das uns zeigt, wie man eine Zufallszahl erstellt

Humphrey
quelle
6
Wenn Ihre Zeichenfolge nur auf einer zufälligen Ganzzahl basiert, warum nicht einfach die zufällige Ganzzahl verwenden? Der Heuhaufen wird nicht tiefer, indem er ihn hasht ... und indem er den Hash von dir schneidet, wird die kleine Entropie, mit der du anfangen musstest, tatsächlich zerstört.
The Surrican
4
Beachten Sie, md5dass dies zu einer Beschränkung auf 30 Zeichen und immer zu Kleinbuchstaben führt.
Fyrye
3
Außerdem sollte rand () nicht für die Kryptografie verwendet werden. Wenn Sie eine krypografisch einwandfreie Zeichenfolge generieren möchten, verwenden Sie openssl_random_pseudo_bytes .
Mattkgross
md5(rand())bietet nur 2 ^ 32 mögliche Werte. Dies bedeutet, dass Sie nach durchschnittlich 2 ^ 16 zufälligen Zeichenfolgen eine Wiederholung erwarten.
Scott Arciszewski
2
Nun ... ich würde wetten, dass das OP nicht von "sicher zufälligen Strings" spricht. Diese Lösung ist kompakt, einfach und für die richtigen Anwendungsfälle gut zu merken . Und wenn Sie sich um mögliche Kollisionen kümmern müssen, warum nicht einen Zeitstempel an die zufällige Zeichenfolge anhängen? :)
Erenor Paz
46

Abhängig von Ihrer Anwendung (ich wollte Passwörter generieren) können Sie verwenden

$string = base64_encode(openssl_random_pseudo_bytes(30));

Als base64 können sie =oder enthalten- sowie die angeforderten Zeichen enthalten. Sie können eine längere Zeichenfolge generieren, diese dann filtern und zuschneiden, um diese zu entfernen.

openssl_random_pseudo_bytesscheint der empfohlene Weg zu sein, um eine richtige Zufallszahl in PHP zu generieren. Warum randnicht verwendet /dev/random, weiß ich nicht.

rjmunro
quelle
2
rand verwendet / dev / urandom nicht, da dies nur in posix-ähnlichen Umgebungen verfügbar und nicht portabel ist.
MacroMan
3
@MacroMan Aber openssl_random_pseudo_bytes() ist tragbar.
Ja͢ck
Wenn Sie die zusätzlichen base64-Zeichen entfernen
möchten
3
Dies ist nicht falsch, aber ich würde zur Vorsicht raten, wie Sie die unerwünschten Zeichen verwerfen. Siehe diese Pull-Anfrage beispielsweise auf dem OAuth2-Server der PHP-Liga .
Scott Arciszewski
Dies ist eine der besten Antworten. Schade, dass es nicht mehr Unterstützung gibt. Ich würde jedoch empfehlen, Ihre Antwort zu bearbeiten, um unerwünschte Zeichen besser behandeln zu können.
Jcuenod
28

Hier ist ein einfacher Einzeiler, der eine echte Zufallszeichenfolge ohne Schleifen auf Skriptebene oder Verwendung von OpenSSL-Bibliotheken generiert.

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

Um es aufzuschlüsseln, damit die Parameter klar sind

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

Diese Methode wiederholt die Zeichenliste nach dem Zufallsprinzip, mischt dann die kombinierte Zeichenfolge und gibt die angegebene Anzahl von Zeichen zurück.

Sie können dies weiter randomisieren, indem Sie die Länge der zurückgegebenen Zeichenfolge randomisieren und $chrRandomLengthdurch mt_rand(8, 15)(für eine zufällige Zeichenfolge zwischen 8 und 15 Zeichen) ersetzen .

Kraang Prime
quelle
Es tut mir leid zu sagen, aber wenn ein Charakter ausgewählt wird, ist seine Wahrscheinlichkeit, erneut aufzutreten, nicht so hoch wie die anderen Charaktere, die noch im Pool verbleiben. Keine echte Zufälligkeit hier ...
The Surrican
@TheSurrican - Sie würden in dieser Aussage falsch sein. Alle Zeichen haben mit diesem Algorithmus die gleiche Wahrscheinlichkeit und sind daher wirklich zufällig. Dies wird durch Wiederholen der chrList-Zeichenfolge $ chrRepeatMax sichergestellt, und die Magie geschieht wirklich in str_shuffle, das die Zufälligkeit bestimmt.
Kraang Prime
Alle Zeichen würden nur einmal erscheinen und es ist sehr anfällig für Bruteforce-Vermutungen
Venimus
@venimus Das ist falsch. Die Zeichenfolge wird für so viele Zeichen dupliziert, wie Sie möchten (siehe $chrRepeatMaxund $chrRepeatMin). Eine Zeichenfolge mit 10 Zeichen kann also (unwahrscheinlich, aber möglich) "aaaaaaaaa" sein.
Kraang Prime
@SanuelJackson Sorry, ich habe falsch kommentiert. Ich habe die falsche Antwort kommentiert. Sie haben Recht! Ich habe tatsächlich Ihren "Trick" verwendet, aber mt_rand nicht verwendet, weil es meiner Meinung nach nutzlos ist. Es trägt nicht zur Entropie bei. Gerade const mit der maximalen Länge verwendet.
Venimus
25
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Tada!

Davor
quelle
Beachten Sie, sha1dass dies zu einer Beschränkung auf 40 Zeichen und immer zu Kleinbuchstaben führt.
Fyrye
3
sha1-Zeichenfolgen sind nicht zufällig, bestimmte Zeichen treten häufiger auf als andere. Es wäre unklug, dies in Fällen zu verwenden, in denen Sie wirklich Zufälligkeit wünschen, wie bei Passwörtern.
Kit Sunde
1
@KitSunde - ja, sha ist nicht zufällig, rand () ist zufällig. Und sha ist vollkommen in Ordnung für das, was hier gebraucht wird. OP benötigt keine Krypto-Zufälligkeit.
Davor
@Davor rant()zufällig zu sein spielt keine Rolle, wenn sha nicht gleichmäßig verteilt ist. Wenn Sie zufällig aus einer ungleichmäßigen Verteilung auswählen, erhalten Sie genau die gleiche ungleichmäßige Verteilung. Es ist keine Zufälligkeit auf "Krypto-Ebene", die ich hervorhole. Wenn dies der Fall wäre, sollten Sie sie auch nicht verwenden rand(). Es erfordert nur minimalen Aufwand, aus einer gleichmäßigen Verteilung wie in der akzeptierten Antwort zu pflücken, und es ist so zufällig wie rand (), was vernünftigerweise so ist.
Kit Sunde
@KitSunde - es macht am Ende buchstäblich keinen Unterschied. Das ist genau die Definition von Überentwicklung und Vergoldung.
Davor
24

Eine bessere Möglichkeit, diese Funktion zu implementieren, ist:

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_randnach mehr zufällig dies und dies in PHP 7. Die randFunktion ein Alias ist mt_rand.

Rathienth Baskaran
quelle
1
Achtung: mt_randGeneriert keine kryptografisch sicheren Werte. Dafür sollten Sie PHP7 random_intoder verwenden random_bytes.
Jchook
18

$randstringim Funktionsumfang ist nicht derselbe wie der Bereich, in dem Sie ihn aufrufen. Sie müssen den Rückgabewert einer Variablen zuweisen.

$randstring = RandomString();
echo $randstring;

Oder geben Sie den Rückgabewert direkt wieder:

echo RandomString();

Auch in Ihrer Funktion haben Sie einen kleinen Fehler. Innerhalb der for-Schleife müssen Sie verwenden, .=damit jedes Zeichen an die Zeichenfolge angehängt wird. Wenn =Sie verwenden, überschreiben Sie es mit jedem neuen Zeichen, anstatt es anzuhängen.

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

Zunächst definieren Sie das Alphabet, das Sie verwenden möchten:

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

Verwenden Sie dann, um openssl_random_pseudo_bytes()die richtigen Zufallsdaten zu generieren:

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

Schließlich verwenden Sie diese zufälligen Daten, um das Passwort zu erstellen. Da für jedes Zeichen in $randomsein kann , chr(0)bis chr(255)verwendet der Code , den Rest nach der Teilung seines Ordinalwertes mit $alphabet_lengthum sicherzustellen , dass nur Zeichen aus dem Alphabet werden gepflückt (beachten Sie, dass dabei die Zufälligkeit so vorbelastet):

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

Alternativ und im Allgemeinen besser ist die Verwendung von RandomLib und SecurityLib :

use SecurityLib\Strength;

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

$password = $generator->generateString(12, $alphabet);
Ja͢ck
quelle
Die Verwendung des Modulo-Operators %erzeugt eine voreingenommene Ausgabe. Allerdings stark +1 für RandomLib. Das Rad nicht neu erfinden.
Scott Arciszewski
1
Ja, die neue Funktion random_int () ist nett: D
Ja͢ck
11

Kurze Methoden ..

Hier sind einige der kürzesten Methoden zum Generieren der zufälligen Zeichenfolge

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

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

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

Ich habe die Leistung der gängigsten Funktionen dort getestet. Die Zeit, die benötigt wird, um 1'000'000 Zeichenfolgen mit 32 Symbolen auf meiner Box zu generieren, beträgt:

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

Bitte beachten Sie, dass es nicht wichtig ist, wie lange es wirklich gedauert hat, sondern welche langsamer und welche schneller ist, damit Sie entsprechend Ihren Anforderungen auswählen können, einschließlich Kryptografie-Bereitschaft usw.

substr () um MD5 wurde aus Gründen der Genauigkeit hinzugefügt, wenn Sie eine Zeichenfolge benötigen, die kürzer als 32 Symbole ist.

Zur Beantwortung: Die Zeichenfolge wurde nicht verkettet, sondern überschrieben, und das Ergebnis der Funktion wurde nicht gespeichert.

Putnik
quelle
Ich denke, diese beste Antwort. Vielen Dank!
NSukonny
10

PHP 7+ Generieren Sie mit der Funktion random_bytes kryptografisch sichere Zufallsbytes .

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

Mögliche Ausgabe

da821217e61e33ed4b2dd96f8439056c


PHP 5.3+ Generieren Sie pseudozufällige Bytes mit der Funktion openssl_random_pseudo_bytes .

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

Mögliche Ausgabe

e2d1254506fbb6cd842cd640333214ad


Der beste Anwendungsfall könnte sein

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

Mögliche Ausgabe

ba8cc342bdf91143

Madan Sapkota
quelle
Dadurch wird kein String mit der angegebenen Länge generiert
Timberman
@ Timberman wird jetzt die genaue Länge generieren.
Madan Sapkota
9

Ein sehr schneller Weg ist, etwas zu tun wie:

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

Dadurch wird eine zufällige Zeichenfolge mit einer Länge von 10 Zeichen generiert. Natürlich könnten einige sagen, dass es auf der Berechnungsseite etwas schwerer ist, aber heutzutage sind Prozessoren so optimiert, dass sie den md5- oder sha256-Algorithmus sehr schnell ausführen. Und wenn die rand()Funktion denselben Wert zurückgibt, ist das Ergebnis natürlich dasselbe und es besteht eine Chance von 1/32767, dass es dasselbe ist. Wenn Sicherheit das Problem ist, wechseln Sie einfach rand()zumt_rand()

Akatosh
quelle
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;
}
Руслан Ибрагимов
quelle
4
Dies ist nicht tragbar; Wenn Sie versuchen, dies in einer Nicht-Posix-Umgebung auszuführen, führt dies zu einem schwerwiegenden Fehler.
Bryan Agee
7

Dieser wurde aus Administratorquellen entnommen :

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

Adminer , in PHP geschriebenes Datenbankverwaltungstool.

userlond
quelle
6

Hilfsfunktion aus dem Laravel 5-Framework

/**
 * 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
quelle
4
"Sollte für Kryptographie usw. nicht als ausreichend angesehen werden." Dies sollte stark betont werden.
Scott Arciszewski
4

Die bearbeitete Version der Funktion funktioniert einwandfrei, aber ich habe nur ein Problem festgestellt: Sie haben das falsche Zeichen verwendet, um $ Zeichen einzuschließen, sodass das Zeichen 'manchmal Teil der zufälligen Zeichenfolge ist, die generiert wird.

Um dies zu beheben, ändern Sie:

$characters = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

zu:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

Auf diese Weise werden nur die eingeschlossenen Zeichen verwendet, und das Zeichen 'wird niemals Teil der zufälligen Zeichenfolge sein, die generiert wird.

bmcswee
quelle
4

Ein weiterer Einzeiler, der eine zufällige Zeichenfolge von 10 Zeichen mit Buchstaben und Zahlen generiert. Es erstellt ein Array mit range(passen Sie den zweiten Parameter an, um die Größe festzulegen), durchläuft dieses Array und weist ein zufälliges ASCII-Zeichen (Bereich 0-9 oder az) zu. Anschließend wird das Array implodiert, um eine Zeichenfolge zu erhalten.

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

Hinweis: Dies funktioniert nur in PHP 5.3 und höher

Kasimir
quelle
Endlich eine wirklich zufällige Lösung, kein aufgeblähter Hash einer zufälligen 32-Bit-Ganzzahl oder einer gemischten Zeichenfolge ...
The Surrican
Es gibt nur ein Problem: Zahlen treten genauso häufig auf wie Zeichen, was nicht so zufällig ist, wie ich es gerne hätte. anyaway +1 für die beste Lösung auf dieser Seite. Optimiere das und es ist perfekt.
Der Surrican
Tweak ... so? rand(0, 57-48+122-97)<57-48?...:...? :)
vp_arth
4

Einzeiler.

Es ist schnell für große Saiten mit einer gewissen Einzigartigkeit.

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
Jacob Smith
quelle
md5(rand())ist eine schrecklich unsichere Methode, um eine Zufallszahl zu generieren.
Scott Arciszewski
1
Eine Zeichenfolge mit X-Länge und einer gewissen Einzigartigkeit ist die Absicht. wahre Zufälligkeit ist nicht die Absicht.
Jacob Smith
3

Ich mochte den letzten Kommentar, der openssl_random_pseudo_bytes verwendete, aber es war keine Lösung für mich, da ich immer noch die Zeichen entfernen musste, die ich nicht wollte, und ich konnte keine Zeichenfolge mit festgelegter Länge erhalten. Hier ist meine Lösung ...

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

Hier ist meine einfache einzeilige Lösung, um ein benutzerfreundliches Zufallskennwort zu generieren, mit Ausnahme der Zeichen, die ähnlich aussehen, wie "1" und "l", "O" und "0" usw. Hier sind es 5 Zeichen, aber Sie können es leicht tun ändere es natürlich:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);
rAthus
quelle
Dies ist perfekt, um zufällige ID-Zeichenfolgen zu erstellen, die später bei jquery aufgerufen werden. IDK, wenn es eine gute Praxis ist, aber das hat mir sehr geholfen, ohne eine für wie die akzeptierte Antwort zu verwenden ...
Rodrigo Zuluaga
3

Hier ist eine andere Lösung.

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. Ich benutze PHP 7.2 unter Ubuntu.

Umair Khan
quelle
2

Eine andere Möglichkeit, eine zufällige Zeichenfolge in PHP zu generieren, ist:

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

Hier ist, wie ich es mache, um einen echten eindeutigen Zufallsschlüssel zu erhalten:

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

Sie können time () verwenden, da es sich um einen Unix-Zeitstempel handelt und im Vergleich zu anderen oben genannten Zufällen immer eindeutig ist. Sie können dann die md5-Summe davon generieren und die gewünschte Länge aus der generierten MD5- Zeichenfolge entnehmen . In diesem Fall verwende ich 10 Zeichen und könnte eine längere Zeichenfolge verwenden, wenn ich sie eindeutiger machen möchte.

Ich hoffe das hilft.

Sherpa
quelle
2
Natürlich time()ist es alles andere als einzigartig: Es wird immer wieder den gleichen Wert zurückgeben, bis die aktuelle Sekunde endet. Was hier wirklich Zufälligkeit bietet, ist: Der str_shuffle()Rest des Codes reduziert nur die Stichprobe, aus der Zeichen ausgewählt werden können.
Álvaro González
1
Sie mischen also im Grunde genommen um eine 32-Bit-Ganzzahl. nicht viel Entropie hier ...
The Surrican
2
Ein Angreifer kann den zurückgegebenen Wert erraten time()(es ist nur ein Zeitstempel), es ist eine schwache Quelle der Zufälligkeit.
AL
2

Parametrisierter Einzeiler, der nur native PHP-Funktionen verwendet und seit PHP 5.1.0 funktioniert

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
quelle