PHP: Wie generiere ich eine zufällige, eindeutige, alphanumerische Zeichenfolge?


380

Wie wäre es möglich, eine zufällige, eindeutige Zeichenfolge mit Zahlen und Buchstaben zur Verwendung in einem Überprüfungslink zu generieren? Zum Beispiel, wenn Sie ein Konto auf einer Website erstellen und eine E-Mail mit einem Link erhalten und auf diesen Link klicken müssen, um Ihr Konto zu verifizieren ... ja ... eines davon.

Wie kann ich eine davon mit PHP generieren?

Update: Gerade erinnert uniqid(). Es ist eine PHP-Funktion, die basierend auf der aktuellen Zeit in Mikrosekunden eine eindeutige Kennung generiert. Ich denke, ich werde das nutzen.


Sie benötigen lediglich Zeichenfolgen und gleichmäßig verteilte Zufallszahlen.
Artelius

10
Hey Andrew, du solltest Scottdie richtige Antwort wählen . Scott verwendet den kryptografisch sicheren Psudo-Zufallszahlengenerator (CSPRNG) von OpenSSL, der basierend auf Ihrer Plattform die sicherste Entropiequelle auswählt.
Turm

3
Wer dies nach 2015 liest, schaut bitte hier: paragonie.com/blog/2015/07/… Die meisten Top-Antworten sind mehr oder weniger fehlerhaft ...
rugk

OpenSSL und uniqidsind unsicher. Verwenden Sie so etwas wie Random::alphanumericString($length)oder Random::alphanumericHumanString($length).
Caw

Antworten:


305

Sicherheitshinweis : Diese Lösung sollte nicht in Situationen verwendet werden, in denen die Qualität Ihrer Zufälligkeit die Sicherheit einer Anwendung beeinträchtigen kann. Insbesondere rand()und uniqid()sind keine kryptografisch sicheren Zufallszahlengeneratoren . Siehe Scotts Antwort für eine sichere Alternative.

Wenn Sie es nicht brauchen, um im Laufe der Zeit absolut einzigartig zu sein:

md5(uniqid(rand(), true))

Andernfalls (vorausgesetzt, Sie haben bereits ein eindeutiges Login für Ihren Benutzer festgelegt):

md5(uniqid($your_user_login, true))

90
Beide Methoden garantieren keine Eindeutigkeit - die Länge der Eingabe der md5-Funktion ist größer als die Länge ihrer Ausgabe, und gemäß dem en.wikipedia.org/wiki/Pigeonhole_principle ist die Kollision garantiert. Andererseits ist die Wahrscheinlichkeit, dass mindestens eine Kollision auftritt, umso größer, je größer die Bevölkerung ist, die sich auf Hashes stützt, um die "eindeutige" ID zu erhalten (siehe en.wikipedia.org/wiki/Birthday_problem ). Die Wahrscheinlichkeit mag für die meisten Lösungen gering sein, existiert aber immer noch.
Dariusz Walczak

12
Dies ist keine sichere Methode zum Generieren von Zufallswerten. Siehe Scotts Antwort.
Turm

4
Für E-Mail-Bestätigungen, die relativ bald ablaufen, halte ich die winzige Möglichkeit, dass eine Person eines Tages die E-Mail einer anderen Person bestätigt, für ein vernachlässigbares Risiko. Sie können jedoch jederzeit überprüfen, ob das Token nach dem Erstellen bereits in der Datenbank vorhanden ist, und in diesem Fall einfach ein neues auswählen. Die Zeit, die Sie mit dem Schreiben dieses Codeausschnitts verbringen, wird jedoch wahrscheinlich verschwendet, da er höchstwahrscheinlich nie ausgeführt wird.
Andrew

Beachten Sie, dass md5 hexadezimale Werte zurückgibt, was bedeutet, dass der Zeichensatz auf [0-9] und [af] beschränkt ist.
Thijs Riezebeek

1
md5 kann Kollisionen haben, Sie haben gerade uniqid Vorteil ruiniert
user151496

507

Ich habe nur untersucht, wie ich das gleiche Problem lösen kann, aber ich möchte auch, dass meine Funktion ein Token erstellt, das auch zum Abrufen von Passwörtern verwendet werden kann. Dies bedeutet, dass ich die Fähigkeit des zu erratenden Tokens einschränken muss. Da uniqidbasierend auf der Zeit und laut php.net "der Rückgabewert sich kaum von microtime () unterscheidet", uniqiderfüllt er die Kriterien nicht. PHP empfiehlt, openssl_random_pseudo_bytes()stattdessen kryptografisch sichere Token zu generieren.

Eine schnelle, kurze und präzise Antwort lautet:

bin2hex(openssl_random_pseudo_bytes($bytes))

Dadurch wird eine zufällige Zeichenfolge mit alphanumerischen Zeichen der Länge = $ bytes * 2 generiert. Leider hat dies nur ein Alphabet von [a-f][0-9], aber es funktioniert.


Unten ist die stärkste Funktion, die ich machen könnte, die die Kriterien erfüllt (Dies ist eine implementierte Version von Eriks Antwort).

function crypto_rand_secure($min, $max)
{
    $range = $max - $min;
    if ($range < 1) return $min; // not so random...
    $log = ceil(log($range, 2));
    $bytes = (int) ($log / 8) + 1; // length in bytes
    $bits = (int) $log + 1; // length in bits
    $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
    do {
        $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
        $rnd = $rnd & $filter; // discard irrelevant bits
    } while ($rnd > $range);
    return $min + $rnd;
}

function getToken($length)
{
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
    }

    return $token;
}

crypto_rand_secure($min, $max)funktioniert als Ersatz für rand()oder mt_rand. Es verwendet openssl_random_pseudo_bytes, um eine Zufallszahl zwischen $ min und $ max zu erstellen.

getToken($length)Erstellt ein Alphabet zur Verwendung innerhalb des Tokens und erstellt dann eine Zeichenfolge mit der Länge $length.

EDIT: Ich habe es versäumt, die Quelle zu zitieren - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322

EDIT (PHP7): Mit der Veröffentlichung von PHP7 verfügt die Standardbibliothek nun über zwei neue Funktionen, die die oben genannte Funktion crypto_rand_secure ersetzen / verbessern / vereinfachen können. random_bytes($length)undrandom_int($min, $max)

http://php.net/manual/en/function.random-bytes.php

http://php.net/manual/en/function.random-int.php

Beispiel:

function getToken($length){
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    $max = strlen($codeAlphabet);

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[random_int(0, $max-1)];
    }

    return $token;
}

2
Einverstanden. Die Speicherung von Klartext-Passwörtern ist schrecklich! (Ich verwende Blowfish.) Nachdem das Token generiert wurde, kann der Inhaber des Tokens das Kennwort zurücksetzen, sodass das Token dem Kennwort entspricht, solange es gültig ist (und als solches behandelt wird).
Scott

23
Hey, ich habe Ihren exzellenten Code mit der praktischen Funktionalität der Kohana Text :: random () -Methode kombiniert und dieses Wesentliche erstellt: gist.github.com/raveren/5555297
raveren

9
Perfekt! Ich habe es mit 10 Zeichen als Länge getestet. 100000 Token und immer noch keine Duplikate!
Sharpless512

5
Ich habe diesen Prozess verwendet und fand ihn super langsam. Mit einer Länge von 36 ist das Zeitlimit auf dem Dev-Server abgelaufen. Bei einer Länge von 24 dauerte es noch rund 30 Sekunden. Ich bin mir nicht sicher, was ich falsch gemacht habe, aber es war zu langsam für mich und ich entschied mich für eine andere Lösung.
Shane

5
Sie können auch base64_encodeanstelle von verwenden bin2hex, um eine kürzere Zeichenfolge mit einem größeren Alphabet zu erhalten.
Erjiang

91

Objektorientierte Version der am besten bewerteten Lösung

Ich habe eine objektorientierte Lösung basierend auf Scotts Antwort erstellt:

<?php

namespace Utils;

/**
 * Class RandomStringGenerator
 * @package Utils
 *
 * Solution taken from here:
 * http://stackoverflow.com/a/13733588/1056679
 */
class RandomStringGenerator
{
    /** @var string */
    protected $alphabet;

    /** @var int */
    protected $alphabetLength;


    /**
     * @param string $alphabet
     */
    public function __construct($alphabet = '')
    {
        if ('' !== $alphabet) {
            $this->setAlphabet($alphabet);
        } else {
            $this->setAlphabet(
                  implode(range('a', 'z'))
                . implode(range('A', 'Z'))
                . implode(range(0, 9))
            );
        }
    }

    /**
     * @param string $alphabet
     */
    public function setAlphabet($alphabet)
    {
        $this->alphabet = $alphabet;
        $this->alphabetLength = strlen($alphabet);
    }

    /**
     * @param int $length
     * @return string
     */
    public function generate($length)
    {
        $token = '';

        for ($i = 0; $i < $length; $i++) {
            $randomKey = $this->getRandomInteger(0, $this->alphabetLength);
            $token .= $this->alphabet[$randomKey];
        }

        return $token;
    }

    /**
     * @param int $min
     * @param int $max
     * @return int
     */
    protected function getRandomInteger($min, $max)
    {
        $range = ($max - $min);

        if ($range < 0) {
            // Not so random...
            return $min;
        }

        $log = log($range, 2);

        // Length in bytes.
        $bytes = (int) ($log / 8) + 1;

        // Length in bits.
        $bits = (int) $log + 1;

        // Set all lower bits to 1.
        $filter = (int) (1 << $bits) - 1;

        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));

            // Discard irrelevant bits.
            $rnd = $rnd & $filter;

        } while ($rnd >= $range);

        return ($min + $rnd);
    }
}

Verwendungszweck

<?php

use Utils\RandomStringGenerator;

// Create new instance of generator class.
$generator = new RandomStringGenerator;

// Set token length.
$tokenLength = 32;

// Call method to generate random string.
$token = $generator->generate($tokenLength);

Benutzerdefiniertes Alphabet

Bei Bedarf können Sie ein benutzerdefiniertes Alphabet verwenden. Übergeben Sie einfach eine Zeichenfolge mit unterstützten Zeichen an den Konstruktor oder Setter:

<?php

$customAlphabet = '0123456789ABCDEF';

// Set initial alphabet.
$generator = new RandomStringGenerator($customAlphabet);

// Change alphabet whenever needed.
$generator->setAlphabet($customAlphabet);

Hier sind die Ausgabebeispiele

SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa

Ich hoffe es wird jemandem helfen. Prost!


Es tut mir leid, aber wie führe ich dieses Ding aus? Ich habe $obj = new RandomStringGenerator;aber welche Methode soll ich aufrufen? Vielen Dank.
SG552

@ sg552, Sie sollten die generateMethode wie im obigen Beispiel aufrufen . Übergeben Sie einfach eine Ganzzahl, um die Länge der resultierenden Zeichenfolge anzugeben.
Slava Fomin II

Danke, es funktioniert bei mir, hat es Custom Alphabetaber nicht getan. Ich habe eine leere Ausgabe, wenn ich echo. Wie auch immer, ich bin mir nicht mal sicher, was das zweite Beispiel nützt, Custom Alphabetalso denke ich, ich bleibe einfach beim ersten Beispiel. Vielen Dank.
SG552

1
Schön, aber in den meisten Szenarien ziemlich übertrieben, es sei denn, Ihr Projekt stützt sich stark auf zufällig generierte Codes
dspacejs

1
ja schön, aber übertrieben, besonders wenn man bedenkt, dass es jetzt für PHP 5.7
Andrew

39

Ich bin spät dran, aber ich bin hier mit einigen guten Forschungsdaten, die auf den Funktionen von Scotts Antwort basieren . Deshalb habe ich ein Digital Ocean-Tröpfchen nur für diesen 5-tägigen automatisierten Test eingerichtet und die generierten eindeutigen Zeichenfolgen in einer MySQL-Datenbank gespeichert.

Während dieses Testzeitraums habe ich 5 verschiedene Längen (5, 10, 15, 20, 50) verwendet und für jede Länge wurden +/- 0,5 Millionen Datensätze eingefügt. Während meines Tests erzeugte nur die Länge 5 +/- 3K-Duplikate von 0,5 Millionen und die verbleibenden Längen erzeugten keine Duplikate. Wir können also sagen, dass wir, wenn wir mit Scotts Funktionen eine Länge von 15 oder mehr verwenden, hochzuverlässige eindeutige Zeichenfolgen generieren können. Hier ist die Tabelle mit meinen Forschungsdaten:

Geben Sie hier die Bildbeschreibung ein

Update: Ich habe mit diesen Funktionen eine einfache Heroku-App erstellt, die das Token als JSON-Antwort zurückgibt. Auf die App kann unter https://uniquestrings.herokuapp.com/api/token?length=15 zugegriffen werden

Ich hoffe das hilft.


33

Sie können die UUID (Universally Unique Identifier) ​​verwenden. Sie kann für jeden Zweck verwendet werden, von der Benutzerauthentifizierungszeichenfolge bis zur Zahlungsvorgangs-ID.

Eine UUID ist eine 128-Bit-Zahl mit 16 Oktetten. In seiner kanonischen Form wird eine UUID durch 32 hexadezimale Ziffern dargestellt, die in fünf durch Bindestriche getrennten Gruppen in der Form 8-4-4-4-12 für insgesamt 36 Zeichen (32 alphanumerische Zeichen und vier Bindestriche) angezeigt werden.

function generate_uuid() {
    return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
        mt_rand( 0, 0xffff ),
        mt_rand( 0, 0x0C2f ) | 0x4000,
        mt_rand( 0, 0x3fff ) | 0x8000,
        mt_rand( 0, 0x2Aff ), mt_rand( 0, 0xffD3 ), mt_rand( 0, 0xff4B )
    );

}

// Funktion aufrufen

$transationID = generate_uuid();

Einige Beispielausgaben sind wie folgt:

E302D66D-87E3-4450-8CB6-17531895BF14
22D288BC-7289-442B-BEEA-286777D559F2
51B4DE29-3B71-4FD2-9E6C-071703E1FF31
3777C8C6-9FF5-4C78-AAA2-08A47F555E81
54B91C72-2CF4-4501-A6E9-02A60DCBAE4C
60F75C7C-1AE3-417B-82C8-14D456542CD7
8DE0168D-01D3-4502-9E59-10D665CEBCB2

hoffe es hilft jemandem in der Zukunft :)


Sieht fantastisch aus, zu meiner Liste hinzugefügt!
Mustafa Erdogan

32

Diese Funktion generiert einen Zufallsschlüssel mit Zahlen und Buchstaben:

function random_string($length) {
    $key = '';
    $keys = array_merge(range(0, 9), range('a', 'z'));

    for ($i = 0; $i < $length; $i++) {
        $key .= $keys[array_rand($keys)];
    }

    return $key;
}

echo random_string(50);

Beispielausgabe:

zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8

6
Nach einer Weile kommen Sie zu den gleichen Zahlen
Sharpless512

1
Dies ist nicht völlig zufällig, da es nie mehr als einmal denselben Chacater geben wird.
EricP

16

Ich benutze diesen Einzeiler:

base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));

Dabei ist Länge die Länge der gewünschten Zeichenfolge (teilbar durch 4, andernfalls wird sie auf die nächste durch 4 teilbare Zahl abgerundet.)


6
Es werden nicht immer nur alphanumerische Zeichen zurückgegeben. Es kann Zeichen wie==
user3459110

1
Wenn in einer URL verwendet, base64url_encodekann stattdessen verwendet werden, siehe hier: php.net/manual/en/function.base64-encode.php
Paul

9

Verwenden Sie den folgenden Code, um die Zufallszahl von 11 Zeichen zu generieren oder die Zahl gemäß Ihren Anforderungen zu ändern.

$randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);

oder wir können eine benutzerdefinierte Funktion verwenden, um die Zufallszahl zu generieren

 function randomNumber($length){
     $numbers = range(0,9);
     shuffle($numbers);
     for($i = 0;$i < $length;$i++)
        $digits .= $numbers[$i];
     return $digits;
 }

 //generate random number
 $randomNum=randomNumber(11);

3
Dies kann niemals die Zeichenfolge "aaaaaaaaaaa" oder "aaaaabbbbbb" erzeugen. Es wird nur eine Teilzeichenfolge einer zufälligen Permutation des Alphabets ausgewählt. Die 11 Zeichen lange Zeichenfolge hat nur V (11,35) = 288 mögliche Werte. Verwenden Sie dies nicht, wenn Sie erwarten, dass die Zeichenfolgen eindeutig sind!
kdojeteri

@Peping dann tunsubstr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstvwxyz', 36)), 0, 11);
Tim Hallman

7
  1. Generieren Sie eine Zufallszahl mit Ihrem bevorzugten Zufallszahlengenerator
  2. Multiplizieren und dividieren Sie es, um eine Zahl zu erhalten, die der Anzahl der Zeichen in Ihrem Code-Alphabet entspricht
  3. Holen Sie sich das Element an diesem Index in Ihr Code-Alphabet.
  4. Wiederholen Sie ab 1), bis Sie die gewünschte Länge haben

zB (im Pseudocode)

int myInt = random(0, numcharacters)
char[] codealphabet = 'ABCDEF12345'
char random = codealphabet[i]
repeat until long enough

Könnte dies theoretisch nicht dazu führen, dass dieselbe Zeichenfolge mehr als einmal generiert wird?
Frezq

4

Hier ist der ultimative einzigartige ID-Generator für Sie. von mir gemacht.

<?php
$d=date ("d");
$m=date ("m");
$y=date ("Y");
$t=time();
$dmt=$d+$m+$y+$t;    
$ran= rand(0,10000000);
$dmtran= $dmt+$ran;
$un=  uniqid();
$dmtun = $dmt.$un;
$mdun = md5($dmtran.$un);
$sort=substr($mdun, 16); // if you want sort length code.

echo $mdun;
?>

Sie können jede 'var' für Ihre ID nach Belieben wiedergeben. aber $ mdun ist besser, Sie können md5 durch sha1 ersetzen, um besseren Code zu erhalten, aber das wird sehr lang sein, was Sie vielleicht nicht brauchen.

Vielen Dank.


7
In diesem Fall wird die Zufälligkeit durch zufällig geschriebenen Code garantiert, oder?
Daniel Kucal

3
Ja, das ist eine Art "zufällig", weil es kein standardmäßiger, obskurer Code ist. Dies macht es schwierig vorherzusagen ... aber es werden keine unsicheren Teile verwendet, um eine Zufallszahl zu generieren. Das Ergebnis ist also technisch nicht zufällig oder sicher.
Philipp

4

Für wirklich zufällige Zeichenfolgen können Sie verwenden

<?php

echo md5(microtime(true).mt_Rand());

Ausgänge:

40a29479ec808ad4bcff288a48a25d5c

Selbst wenn Sie versuchen, einen String mehrmals genau zur gleichen Zeit zu generieren, erhalten Sie unterschiedliche Ausgaben.


4

Wenn Sie versuchen, ein zufälliges Passwort zu generieren, versuchen Sie:

  • Generieren Sie zunächst einen kryptografisch sicheren Satz zufälliger Bytes

  • Zweitens werden diese zufälligen Bytes in eine druckbare Zeichenfolge umgewandelt

Jetzt gibt es mehrere Möglichkeiten, zufällige Bytes in PHP zu generieren, wie:

$length = 32;

//PHP 7+
$bytes= random_bytes($length);

//PHP < 7
$bytes= openssl_random_pseudo_bytes($length);

Dann möchten Sie diese zufälligen Bytes in eine druckbare Zeichenfolge umwandeln:

Sie können bin2hex verwenden :

$string = bin2hex($bytes);

oder base64_encode :

$string = base64_encode($bytes);

Beachten Sie jedoch, dass Sie die Länge der Zeichenfolge nicht steuern, wenn Sie base64 verwenden. Sie können dazu bin2hex verwenden. Die Verwendung von 32 Bytes wird zu einer Zeichenfolge mit 64 Zeichen . Aber es wird nur so in einer EVEN- Zeichenfolge funktionieren .

Im Grunde können Sie also einfach Folgendes tun :

$length = 32;

if(PHP_VERSION>=7){
    $bytes= random_bytes($length);
}else{
    $bytes= openssl_random_pseudo_bytes($length);
} 

$string = bin2hex($bytes);

3

Folgendes benutze ich:

md5(time() . rand());    
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b

2
function random_string($length = 8) {
    $alphabets = range('A','Z');
    $numbers = range('0','9');
    $additional_characters = array('_','=');
    $final_array = array_merge($alphabets,$numbers,$additional_characters);
       while($length--) {
      $key = array_rand($final_array);

      $password .= $final_array[$key];
                        }
  if (preg_match('/[A-Za-z0-9]/', $password))
    {
     return $password;
    }else{
    return  random_string();
    }

 }

2

Dies ist eine einfache Funktion, mit der Sie zufällige Zeichenfolgen mit Buchstaben und Zahlen (alphanumerisch) generieren können. Sie können auch die Zeichenfolgenlänge begrenzen. Diese zufälligen Zeichenfolgen können für verschiedene Zwecke verwendet werden, einschließlich: Empfehlungscode, Aktionscode, Gutscheincode. Die Funktion basiert auf folgenden PHP-Funktionen: base_convert, sha1, uniqid, mt_rand

function random_code($length)
{
  return substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, $length);
}

echo random_code(6);

/*sample output
* a7d9e8
* 3klo93
*/

1

Nachdem ich die vorherigen Beispiele gelesen hatte, kam ich auf Folgendes:

protected static $nonce_length = 32;

public static function getNonce()
{
    $chars = array();
    for ($i = 0; $i < 10; $i++)
        $chars = array_merge($chars, range(0, 9), range('A', 'Z'));
    shuffle($chars);
    $start = mt_rand(0, count($chars) - self::$nonce_length);
    return substr(join('', $chars), $start, self::$nonce_length);
}

Ich dupliziere das Array 10-mal [0-9, AZ] und mische die Elemente, nachdem ich einen zufälligen Startpunkt für substr () erhalten habe, um kreativer zu sein :) Sie können dem Array [az] und andere Elemente hinzufügen, duplizieren Sei mehr oder weniger kreativer als ich


1

Ich verwende gerne Hash-Schlüssel, wenn ich Verifizierungslinks verarbeite. Ich würde empfehlen, die Mikrozeit zu verwenden und MD5 zu verwenden, da es keinen Grund geben sollte, warum die Schlüssel gleich sein sollten, da sie auf der Mikrozeit basieren.

  1. $key = md5(rand());
  2. $key = md5(microtime());

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

}

?>

Die obige Funktion generiert eine zufällige Zeichenfolge mit einer Länge von 11 Zeichen.


1

Wenn Sie eine eindeutige Zeichenfolge in PHP generieren möchten, versuchen Sie Folgendes.

md5(uniqid().mt_rand());

In diesem,

uniqid()- Es wird eine eindeutige Zeichenfolge generiert. Diese Funktion gibt einen auf einem Zeitstempel basierenden eindeutigen Bezeichner als Zeichenfolge zurück.

mt_rand() - Zufallszahl generieren.

md5() - Es wird die Hash-Zeichenfolge generiert.


0

Scott, ja du bist sehr schreibend und gute Lösung! Vielen Dank.

Ich muss außerdem für jeden Benutzer ein eindeutiges API-Token generieren. Im Folgenden ist mein Ansatz, ich habe Benutzerinformationen (Benutzer-ID und Benutzername) verwendet:

public function generateUniqueToken($userid, $username){

        $rand = mt_rand(100,999);
    $md5 = md5($userid.'!(&^ 532567_465 ///'.$username);

    $md53 = substr($md5,0,3);
    $md5_remaining = substr($md5,3);

    $md5 = $md53. $rand. $userid. $md5_remaining;

    return $md5;
}

Bitte schauen Sie und lassen Sie mich wissen, ob ich Verbesserungen vornehmen kann. Vielen Dank


0

Folgendes verwende ich für eines meiner Projekte: Es funktioniert hervorragend und generiert ein EINZIGARTIGES ZUFÄLLIGES TOKEN :

$timestampz=time();

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


$tokenparta = generateRandomString();


$token = $timestampz*3 . $tokenparta;

echo $token;

Bitte beachten Sie, dass ich den Zeitstempel mit drei multipliziert habe, um Verwirrung zu stiften für jeden Benutzer, der sich fragt, wie dieses Token generiert wird;)

Ich hoffe, es hilft :)


1
"Bitte beachten Sie, dass ich den Zeitstempel mit drei multipliziert habe, um Verwirrung zu stiften, wenn sich ein Benutzer fragt, wie dieses Token generiert wird." Klingt nach Sicherheit durch Verschleierung stackoverflow.com/questions/533965/…
Harry

Dies ist keine "Sicherheit durch Verschleierung", da der Zeitstempel dann zu einer zufälligen Zeichenfolge hinzugefügt wird, die generiert wurde, und dies ist die tatsächliche endgültige Zeichenfolge, die wir zurückgeben;)
Kaszoni Ferencz


0

Wir können diese beiden Codezeilen verwenden, um eine eindeutige Zeichenfolge zu generieren, die etwa 10000000 Mal iteriert wurde

  $sffledStr= str_shuffle('abscdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+');
    $uniqueString = md5(time().$sffledStr);

0

Ich benutze diese Funktion immer, um eine benutzerdefinierte zufällige alphanumerische Zeichenfolge zu generieren ... Hoffe diese Hilfe.

<?php
  function random_alphanumeric($length) {
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345689';
    $my_string = '';
    for ($i = 0; $i < $length; $i++) {
      $pos = mt_rand(0, strlen($chars) -1);
      $my_string .= substr($chars, $pos, 1);
    }
    return $my_string;
  }
  echo random_alphanumeric(50); // 50 characters
?>

Es generiert zum Beispiel: Y1FypdjVbFCFK6Gh9FDJpe6dciwJEfV6MQGpJqAfuijaYSZ86g

Wenn Sie mit einer anderen Zeichenfolge vergleichen möchten, um sicherzustellen, dass es sich um eine eindeutige Sequenz handelt, können Sie diesen Trick verwenden ...

$string_1 = random_alphanumeric(50);
$string_2 = random_alphanumeric(50);
while ($string_1 == $string_2) {
  $string_1 = random_alphanumeric(50);
  $string_2 = random_alphanumeric(50);
  if ($string_1 != $string_2) {
     break;
  }
}
echo $string_1;
echo "<br>\n";
echo $string_2;

Es werden zwei eindeutige Zeichenfolgen generiert:

qsBDs4JOoVRfFxyLAOGECYIsWvpcpMzAO9pypwxsqPKeAmYLOi

Ti3kE1WfGgTNxQVXtbNNbhhvvapnaUfGMVJecHkUjHbuCb85pF

Hoffe das ist was du suchst ...


0

Eine einfache Lösung besteht darin, die Basis 64 in alphanumerische Zeichen umzuwandeln, indem die nicht alphanumerischen Zeichen verworfen werden.

Dieser verwendet random_bytes () für ein kryptografisch sicheres Ergebnis.

function random_alphanumeric(int $length): string
{
    $result='';
    do
    {
        //Base 64 produces 4 characters for each 3 bytes, so most times this will give enough bytes in a single pass
        $bytes=random_bytes(($length+3-strlen($result))*2);
        //Discard non-alhpanumeric characters
        $result.=str_replace(['/','+','='],['','',''],base64_encode($bytes));
        //Keep adding characters until the string is long enough
        //Add a few extra because the last 2 or 3 characters of a base 64 string tend to be less diverse
    }while(strlen($result)<$length+3);
    return substr($result,0,$length);
}


-1

Ich glaube, das Problem bei allen vorhandenen Ideen ist, dass sie wahrscheinlich einzigartig, aber nicht definitiv einzigartig sind (wie in Dariusz Walczaks Antwort auf Loletech ausgeführt). Ich habe eine Lösung, die eigentlich einzigartig ist. Es erfordert, dass Ihr Skript über eine Art Speicher verfügt. Für mich ist dies eine SQL-Datenbank. Sie können auch einfach irgendwo in eine Datei schreiben. Es gibt zwei Implementierungen:

Erste Methode: Haben Sie ZWEI Felder anstelle von 1, die die Eindeutigkeit gewährleisten. Das erste Feld ist eine ID-Nummer, die nicht zufällig, sondern eindeutig ist (Die erste ID ist 1, die zweite 2 ...). Wenn Sie SQL verwenden, definieren Sie einfach das ID-Feld mit der Eigenschaft AUTO_INCREMENT. Das zweite Feld ist nicht eindeutig, sondern zufällig. Dies kann mit jeder anderen Technik erzeugt werden, die bereits erwähnt wurde. Scotts Idee war gut, aber md5 ist praktisch und wahrscheinlich für die meisten Zwecke gut genug:

$random_token = md5($_SERVER['HTTP_USER_AGENT'] . time());

Zweite Methode: Grundsätzlich die gleiche Idee, aber zunächst eine maximale Anzahl von Zeichenfolgen auswählen, die jemals generiert werden. Dies könnte nur eine wirklich große Zahl wie eine Billion sein. Machen Sie dann dasselbe, generieren Sie eine ID, aber füllen Sie sie mit Null auf, sodass alle IDs die gleiche Anzahl von Ziffern haben. Dann verketten Sie einfach die ID mit der zufälligen Zeichenfolge. Für die meisten Zwecke ist es zufällig genug, aber der ID-Abschnitt stellt sicher, dass es auch eindeutig ist.


-1

Sie können diesen Code verwenden, ich hoffe, er wird für Sie hilfreich sein.

function rand_code($len)
{
 $min_lenght= 0;
 $max_lenght = 100;
 $bigL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 $smallL = "abcdefghijklmnopqrstuvwxyz";
 $number = "0123456789";
 $bigB = str_shuffle($bigL);
 $smallS = str_shuffle($smallL);
 $numberS = str_shuffle($number);
 $subA = substr($bigB,0,5);
 $subB = substr($bigB,6,5);
 $subC = substr($bigB,10,5);
 $subD = substr($smallS,0,5);
 $subE = substr($smallS,6,5);
 $subF = substr($smallS,10,5);
 $subG = substr($numberS,0,5);
 $subH = substr($numberS,6,5);
 $subI = substr($numberS,10,5);
 $RandCode1 = str_shuffle($subA.$subD.$subB.$subF.$subC.$subE);
 $RandCode2 = str_shuffle($RandCode1);
 $RandCode = $RandCode1.$RandCode2;
 if ($len>$min_lenght && $len<$max_lenght)
 {
 $CodeEX = substr($RandCode,0,$len);
 }
 else
 {
 $CodeEX = $RandCode;
 }
 return $CodeEX;
}

Details zum Zufallscodegenerator in PHP


-2

Vereinfachung des obigen Scotts-Codes durch Entfernen unnötiger Schleifen, die sich stark verlangsamen und nicht sicherer machen als das einmalige Aufrufen von openssl_random_pseudo_bytes

function crypto_rand_secure($min, $max)
{
 $range = $max - $min;
 if ($range < 1) return $min; // not so random...
 $log = ceil(log($range, 2));
 $bytes = (int) ($log / 8) + 1; // length in bytes
 $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
 return $min + $rnd%$range;
}

function getToken($length)
{
 return bin2hex(openssl_random_pseudo_bytes($length)
}

Leider kann ich Ihnen nicht zustimmen, dass dies eine angemessene Vereinfachung der Funktion crypto_rand_secure ist. Die Schleife ist erforderlich, um eine Modulo-Verzerrung zu vermeiden, die auftritt, wenn Sie das Ergebnis einer zufällig generierten Zahl nehmen und es dann durch eine Zahl modifizieren, die den Bereich teilt. en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Modulo_bias . Durch die Verwendung einer Schleife zum Herauswerfen von Zahlen außerhalb des Bereichs und die Auswahl einer neuen Zahl wird diese Verzerrung vermieden. stackoverflow.com/questions/10984974/…
Scott

@ Scott, in diesem Beitrag geht es um rand (). In diesem Fall wird es jedoch bereits von openssl_random_pseudo_bytes erledigt, sodass eine unnötige Schleife erforderlich ist.
Mabel

1
gist.github.com/anonymous/87e3ae6fd3320447f46b973e75c2ea85 - Bitte führen Sie dieses Skript aus. Sie werden sehen, dass die Verteilung der Ergebnisse nicht zufällig ist. Zahlen zwischen 0 und 55 treten häufiger auf als Zahlen zwischen 56 und 100. opensslverursacht dies nicht, sondern liegt an der Modulo-Verzerrung in Ihrer return-Anweisung. 100 (Bereich) teilt 255 (1 Byte) nicht gleichmäßig und verursacht diese Ergebnisse. Mein größtes Problem mit Ihrer Antwort ist, dass Sie angeben, dass die Funktion so sicher ist wie die Verwendung einer Schleife, was falsch ist. Ihre Implementierung von crypto_rand_secure ist nicht kryptografisch sicher und irreführend.
Scott

@Scott, wir schweifen hier ab, es geht nicht um die letzte return-Anweisung, sie kann auch progressiv aus dem Rückgabewert von openssl_random_pseudo_bytes berechnet werden, ohne modulo zu verwenden. Der Punkt, den ich mache, ist, dass die Schleife unnötig ist, sobald openssl_random_pseudo_bytes die zufälligen Bytes zurückgibt. Indem Sie eine Schleife erstellen, machen Sie sie nicht sicherer, sondern nur langsam.
Mabel

2
Diese Antwort verbreitet schlechte Informationen. Sie haben Recht, dass die Schleife nicht opensslsicherer ist, aber was noch wichtiger ist, sie macht sie nicht weniger sicher, diese Antwort tut es. Der obige Code nimmt eine vollkommen gute Zufallszahl und zerlegt sie, indem er sie auf niedrigere Zahlen ausrichtet. Wenn Sie Ihrer Antwort einen Haftungsausschluss hinzufügen, der besagt, dass sie schneller ist (indem Sie die Schleife entfernen), es sich jedoch nicht um eine CSPRNG handelt, wird dieses Problem behoben. Bitte lassen Sie die Benutzer aus Liebe zur Krypto wissen, dass die Ausgabe dieser Funktion verzerrt sein kann und keine gleichwertige Lösung darstellt. Die Schleife ist nicht nur da, um Sie zu ärgern.
Scott
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.