string länge - Wie erstelle ich eine zufällige Zeichenfolge mit PHP?




meta description (15)

function generate_random_string($name_length = 8) {
    $alpha_numeric = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    return substr(str_shuffle(str_repeat($alpha_numeric, $name_length)), 0, $name_length);
}

Der Code wurde mzhang dem großen Vorschlag von mzhang in den Kommentaren unten aktualisiert.

Ich weiß, dass die Rand-Funktion in PHP zufällige Ganzzahlen erzeugt, aber was ist der beste Weg, um eine zufällige Zeichenfolge zu generieren, wie zum Beispiel:

Originalsaite, 9 Zeichen

$string = 'abcdefghi';

Beispiel für eine zufällige Zeichenfolge, die auf 6 Zeichen beschränkt ist

$string = 'ibfeca';

UPDATE: Ich habe Tonnen dieser Arten von Funktionen gefunden, im Grunde versuche ich, die Logik hinter jedem Schritt zu verstehen.

UPDATE: Die Funktion sollte beliebig viele Zeichen generieren.

Bitte kommentiere die Teile, wenn du antwortest.


Das Verbinden von Zeichen am Ende sollte effizienter sein als die wiederholte String-Verkettung.

Edit # 1: Option hinzugefügt, um Zeichenwiederholung zu vermeiden.

Edit # 2: Wirft eine Exception aus, um zu vermeiden, in eine Endlosschleife zu gelangen, wenn $ norepeat ausgewählt ist und $ len größer als der Zeichensatz ist, aus dem ausgewählt werden soll.

Edit # 3: Verwendet Array-Schlüssel zum Speichern ausgewählter zufälliger Zeichen, wenn $ norepeat ausgewählt ist, da das Suchen nach assoziativen Array-Schlüsseln schneller ist als das lineare Durchsuchen des Arrays.

function rand_str($len, $norepeat = true)
{
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $max = strlen($chars) - 1;

    if ($norepeat && len > $max + 1) {
        throw new Exception("Non repetitive random string can't be longer than charset");
    }

    $rand_chars = array();

    while ($len) {
        $picked = $chars[mt_rand(0, $max)];

        if ($norepeat) {
            if (!array_key_exists($picked, $rand_chars)) {
                $rand_chars[$picked] = true;
                $len--;
            }
        }
        else {
            $rand_chars[] = $picked;
            $len--;
        }
    }

    return implode('', $norepeat ? array_keys($rand_chars) : $rand_chars);   
}

Sie könnten ein Array von Zeichen erstellen und dann mit rand () einen Buchstaben aus dem Array auswählen und zu einer Zeichenfolge hinzufügen.

$letters = array( [0] => 'a' [1] => 'b' [2] => 'c' [3] => 'd' ... [25] = 'z');

$lengthOfString = 10;
$str = '';

while( $lengthOfString-- )
{
   $str .= $letters[rand(0,25)];
}
echo $str;

* Beachten Sie, dass dies Wiederholungszeichen erlaubt


Nun, ich suchte nach einer Lösung und nutzte @Chad Birchs Lösung, die mit der von @ Gumbo verschmolzen wurde. Das ist, was ich mir ausgedacht habe:

function get_random_string($length, $valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456790!·$%&/()=?¿¡',.-;:+*`+´ç")
{
    $random_string = "";
    $num_valid_chars = strlen($valid_chars);
    for ($i = 0; $i < $length; $i++, $random_string .= $valid_chars[mt_rand(1, $num_valid_chars)-1]);
    return $random_string;
}

Ich denke, Kommentare sind ziemlich unnötig, da die Antworten, die ich verwendet habe, bereits ausführlich kommentiert wurden. Prost!


Ich denke, ich werde meinen Beitrag hier hinzufügen.

function random_string($length) {
    $bytes_1 = openssl_random_pseudo_bytes($length);
    $hex_1 = bin2hex($bytes_1);
    $random_numbers = substr(sha1(rand()), 0, $length);
    $bytes_2 = openssl_random_pseudo_bytes($length);
    $hex_2 = bin2hex($bytes_2);
    $combined_chars = $hex_1 . $random_numbers . $hex_2;
    $chars_crypted = hash('sha512', $combined_chars);

    return $chars_crypted;
}

Vielen Dank


Nun, Sie haben nicht alle Fragen geklärt, die ich in meinem Kommentar gestellt habe, aber ich nehme an, dass Sie eine Funktion wünschen, die eine Zeichenfolge von "möglichen" Zeichen und eine Länge von Zeichenfolgen zurückgeben kann. Wurde ausführlich wie gewünscht kommentiert, wobei zur besseren Übersichtlichkeit mehr Variablen verwendet wurden als normalerweise:

function get_random_string($valid_chars, $length)
{
    // start with an empty random string
    $random_string = "";

    // count the number of chars in the valid chars string so we know how many choices we have
    $num_valid_chars = strlen($valid_chars);

    // repeat the steps until we've created a string of the right length
    for ($i = 0; $i < $length; $i++)
    {
        // pick a random number from 1 up to the number of valid chars
        $random_pick = mt_rand(1, $num_valid_chars);

        // take the random character out of the string of valid chars
        // subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
        $random_char = $valid_chars[$random_pick-1];

        // add the randomly-chosen char onto the end of our string so far
        $random_string .= $random_char;
    }

    // return our finished random string
    return $random_string;
}

Um diese Funktion mit Ihren Beispieldaten aufzurufen, würden Sie Folgendes nennen:

$original_string = 'abcdefghi';
$random_string = get_random_string($original_string, 6);

Beachten Sie, dass diese Funktion nicht nach Eindeutigkeit in den gültigen Zeichen sucht, die an sie übergeben werden. Wenn Sie beispielsweise mit einer gültigen Zeichenfolge 'AAAB' , wäre es dreimal wahrscheinlicher, ein A für jeden Buchstaben als ein B zu wählen. 'AAAB' könnte je nach Ihren Bedürfnissen als Fehler oder als Funktion betrachtet werden.


Eine bessere und aktualisierte Version der ausgezeichneten Antwort von @ taskamiski:

Bessere Version mit mt_rand() anstelle von rand() :

echo md5(mt_rand()); // 32 char string = 128bit

Noch besser, für längere Strings, mit der Funktion hash() , die Hashing-Algorithmen erlaubt:

echo hash('sha256', mt_rand()); // 64 char string
echo hash('sha512', mt_rand()); // 128 char string

Wenn Sie das Ergebnis auf 50 Zeichen reduzieren möchten, machen Sie das so:

echo substr(hash('sha256', mt_rand()), 0, 50); // 50 char string

Dies baut auf der Lösung von Gumbo auf, indem Funktionen hinzugefügt werden, um eine Reihe von Zeichen aufzulisten, die im Basiszeichensatz übersprungen werden. Die zufällige Zeichenfolge wählt Zeichen aus $base_charset , die nicht auch in $skip_charset .

/* Make a random string of length using characters from $charset, excluding $skip_chars.
 * @param length (integer) length of return value
 * @param skip_chars (string) characters to be excluded from $charset
 * @param charset (string) characters of posibilities for characters in return val
 * @return (string) random string of length $length    */
function rand_string(
        $length, 
        $skip_charset = '', 
        $base_charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'){
  $skip_len = strlen($skip_charset);
  for ($i = 0; $i<$skip_len; $i++){
    $base_charset = str_replace($skip_charset[$i], '', $base_charset);
  }
  cvar_dump($base_charset, '$base_charset after replace');
  $str = '';
  $count = strlen($base_charset);
  while ($length--) {
    $str .= $base_charset[mt_rand(0, $count - 1)];
  }
  return $str;
}

Hier sind einige Anwendungsbeispiele. Die ersten beiden Beispiele verwenden den Standardwert für $base_charset . Das letzte Beispiel definiert explizit $base_charset .

echo rand_string(15, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
//  470620078953298
echo rand_string(8, 'abcdefghijklmnopqrstuvwxyz0123456789');
//  UKLIHOTFSUZMFPU
echo rand_string(15, 'def', 'abcdef');
//  cbcbbccbabccaba

Dies erzeugt eine zufällige Zeichenfolge

function generateRandomString($length=10) {
    $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 generateRandomString(6);

Mein Favorit:

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

Wenn Sie sich nicht Gedanken über Zeit, Speicher oder CPU-Effizienz machen und Ihr System damit umgehen kann, warum sollten Sie diesen Algorithmus nicht ausprobieren ?!

function randStr($len, $charset = 'abcdABCD0123') {
    $out = '';
    $str = array();

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        $str[$i] = $charset;

        shuffle($str);
        $charset .= implode($charset, $str);
        $charset = str_shuffle($charset);
    }

    $str = array_flip($str);
    $str = array_keys($str);

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        shuffle($str);
    }

    $str = implode('', $str);

    for ($i = 0; $i < strlen($str); $i++) {
        $index = mt_rand(1, strlen($str));
        $out .= $str[$index - 1];
    }

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        $out = str_shuffle($out);
    }

    return substr($out, 0, $len);
}

Vielleicht wird es besser lesen, wenn es Rekursion verwendet, aber ich bin nicht sicher, ob PHP Tail-Rekursion verwendet oder nicht ...


Möchten Sie Ihr Passwort durch eine zufällige Permutation der ursprünglichen Buchstaben erstellen? Sollte es nur einzigartige Charaktere enthalten?

Verwenden Sie rand , um zufällige Buchstaben nach Index auszuwählen.


Wozu brauchst du eine zufällige Zeichenfolge?

Wird dies für alles verwendet, was einem Passwort analog ist?

Wenn Ihre zufällige Zeichenfolge überhaupt Sicherheitseigenschaften erfordert, sollten Sie die random_int() Funktion von PHP 7 anstelle aller unsicheren mt_rand() -Antworten in diesem Thread verwenden.

/**
 * Generate a random string
 * 
 * @link https://paragonie.com/b/JvICXzh_jhLyt4y3
 *
 * @param int $length - How long should our random string be?
 * @param string $charset - A string of all possible characters to choose from
 * @return string
 */
function random_str($length = 32, $charset = 'abcdefghijklmnopqrstuvwxyz')
{
    // Type checks:
    if (!is_numeric($length)) {
        throw new InvalidArgumentException(
            'random_str - Argument 1 - expected an integer'
        );
    }
    if (!is_string($charset)) {
        throw new InvalidArgumentException(
            'random_str - Argument 2 - expected a string'
        );
    }

    if ($length < 1) {
        // Just return an empty string. Any value < 1 is meaningless.
        return '';
    }
    // This is the maximum index for all of the characters in the string $charset
    $charset_max = strlen($charset) - 1;
    if ($charset_max < 1) {
        // Avoid letting users do: random_str($int, 'a'); -> 'aaaaa...'
        throw new LogicException(
            'random_str - Argument 2 - expected a string at least 2 characters long'
        );
    }
    // Now that we have good data, this is the meat of our function:
    $random_str = '';
    for ($i = 0; $i < $length; ++$i) {
        $r = random_int(0, $charset_max);
        $random_str .= $charset[$r];
    }
    return $random_str;
}

Wenn Sie noch nicht auf PHP 7 sind (was wahrscheinlich der Fall ist, da es noch nicht veröffentlicht wurde), dann wollen Sie paragonie/random_compat , welches eine random_bytes() Implementierung von random_bytes() und random_int() für PHP 5 Projekte.

Verwenden random_int() für Sicherheitskontexte immer random_int() , nicht rand() , mt_rand() usw. Siehe auch ircmaxells Antwort .


Die meisten Aspekte wurden bereits besprochen, aber ich würde ein kleines Update empfehlen: Wenn Sie dies für den Einzelhandel verwenden, würde ich die Domäne ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 vermeiden

und stattdessen verwenden: ABCDEFGHJKMNPQRSTUVWXY3456789

Zugegeben, Sie haben viel weniger Charaktere, aber es erspart Ihnen viel Ärger, da die Kunden nicht 0 für O oder 1 für 1 oder 2 für Z verwechseln können. Außerdem können Sie einen UPPER für die Eingabe machen und Kunden können das dann tun Geben Sie Groß- oder Kleinbuchstaben ein - das ist auch manchmal verwirrend, da sie ähnlich aussehen können.


Ich bin ein bisschen beeindruckt, dass in keiner der Antworten, die strpos , strstr und ähnliche Funktionen verwendet haben, Multibyte-String-Funktionen noch erwähnt wurden (2015-05-08).

Wenn Sie Probleme haben, Wörter zu finden, die für bestimmte Sprachen spezifisch sind , z. B. Deutsch, Französisch, Portugiesisch, Spanisch usw. (z. B. ä , é , ô , ç , º , ñ ), möchten Sie dies vielleicht vorhergehen die Funktionen mit mb_ . Daher würde die akzeptierte Antwort stattdessen " mb_strpos oder " mb_stripos (für Übereinstimmung mb_strpos mb_stripos Groß- und Kleinschreibung):

if (mb_strpos($a,'are') !== false) {
    echo 'true';
}

Wenn Sie nicht garantieren können, dass alle Ihre Daten in UTF-8 zu 100% mb_ , können Sie die mb_ Funktionen verwenden.

Ein guter Artikel, um zu verstehen, warum das absolute Minimum ist, das jeder Softwareentwickler absolut und positiv über Unicode und Zeichensätze (keine Ausreden!) Von Joel Spolsky wissen muss .





php string random