webentwicklung-frage-antwort-db.com.de

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

Wie wäre es möglich, eine zufällige, eindeutige Zeichenfolge aus Zahlen und Buchstaben für die Verwendung in einem Bestätigungslink zu generieren? Zum Beispiel, wenn Sie ein Konto auf einer Website erstellen und eine E-Mail mit einem Link an Sie senden und Sie auf diesen Link klicken müssen, um Ihr Konto zu verifizieren ... ja ... eines davon.

Wie kann ich eine davon mit PHP generieren?

Update: Ich habe mich gerade an uniqid() erinnert. Es ist eine PHP -Funktion, die einen eindeutigen Bezeichner basierend auf der aktuellen Zeit in Mikrosekunden generiert. Ich denke, ich werde das nutzen.

347
Andrew

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 benötigen, 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))
281
loletech

Ich habe nur nach Lösungen für dieses Problem gesucht, 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 Tokens einschränken muss, erraten zu werden. Da uniqid auf der Zeit basiert und laut php.net "der Rückgabewert sich kaum von microtime () unterscheidet", erfüllt uniqid die Kriterien nicht. PHP empfiehlt, stattdessen openssl_random_pseudo_bytes() zu verwenden, um kryptografisch sichere Token zu generieren.

Eine schnelle, kurze und präzise Antwort lautet:

bin2hex(openssl_random_pseudo_bytes($bytes))

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


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) ersetzt 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.

BEARBEITEN: Ich habe 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) und random_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); // edited

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

    return $token;
}
460
Scott

Objektorientierte Version der am häufigsten gewählten Lösung

Ich habe eine objektorientierte Lösung erstellt, die auf der Antwort von Scott basiert:

<?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

Sie können bei Bedarf 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 hilft jemandem. Prost!

86
Slava Fomin II

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

Während dieser Testperiode verwendete ich 5 verschiedene Längen (5, 10, 15, 20, 50) und +/- 0,5 Millionen Datensätze wurden für jede Länge eingefügt. Während meines Tests erzeugten nur die Länge 5 +/- 3K Duplikate von 0,5 Millionen und die verbleibenden Längen erzeugten keine Duplikate. Wenn wir also eine Länge von 15 oder mehr mit Scotts Funktionen verwenden, können wir äußerst zuverlässige eindeutige Zeichenfolgen generieren. Hier ist die Tabelle mit meinen Forschungsdaten:

enter image description here

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

Ich hoffe das hilft.

33
Rehmat

Diese Funktion generiert einen zufälligen Schlüssel aus 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
30

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

Eine UUID ist eine 128-Bit-Zahl. 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 )
    );

}

// aufruf funktion

$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 Zukunft :)

28
Developer

Ich benutze diesen Einzeiler:

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

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

13
DudeOnRock

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

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

oder wir können 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);
7
Ramesh Kotkar
  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 Ihrem Code-Alphabet.
  4. Wiederholen Sie ab 1), bis Sie die gewünschte Länge haben

z. B. (in Pseudocode)

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

Hier ist der ultimative eindeutige 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 jedes 'var' für Ihre ID ausgeben, wie Sie möchten. aber $ mdun ist besser, du kannst md5 durch sha1 ersetzen, um besseren Code zu erhalten, aber das wird sehr lang, was du vielleicht nicht brauchst.

Danke.

4
Krishna Torque

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 eine andere Ausgabe.

3
AMB

Wenn Sie versuchen, ein zufälliges Kennwort zu generieren, versuchen Sie Folgendes:

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

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

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

$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 bin2hex verwenden, um dies zu tun. Wenn Sie 2 Bytes verwenden, wird dies zu 64 Zeichen. Aber es wird nur so in einer EVEN Zeichenfolge funktionieren.

2
Dylan Kas

Folgendes verwende ich:

md5(time() . Rand());    
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b
2
Faraz Kelhini
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
Nidhin

Ich verwende gerne Hash-Schlüssel, wenn ich Verifizierungslinks bearbeite. Ich würde empfehlen, die Mikrotime und das Hashing mit MD5 zu verwenden, da es keinen Grund geben sollte, warum die Schlüssel gleich sein sollten, da die Hashes auf der Mikrotime basieren.

  1. $key = md5(Rand());
  2. $key = md5(microtime());
1
codermjb

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 Zeitstempeln basierenden eindeutigen Bezeichner als Zeichenfolge zurück.

mt_Rand() - Zufallszahl generieren.

md5() - Es wird der Hash-String generiert.

1
akshaypjoshi

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 10-mal das Array [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
Luiggi ZAMOL

Dies ist eine einfache Funktion, mit der Sie zufällige Zeichenfolgen mit Buchstaben und Zahlen (alphanumerisch) generieren können. Sie können auch die Länge der Zeichenfolge begrenzen. Diese zufälligen Zeichenfolgen können für verschiedene Zwecke verwendet werden, einschließlich: Empfehlungscode, Werbecode, Gutscheincode. Die Funktion basiert auf den 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
Arpit J.
<?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.

0

Folgendes verwende ich für eines meiner Projekte: Es funktioniert hervorragend und generiert ein EINZIGARTIGES ZUFALLS-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 eine Verwirrung für jeden Benutzer zu schaffen, der sich fragen mag, wie dieses Token generiert wird.

Ich hoffe, es hilft :)

0
Kaszoni Ferencz

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

Ich muss außerdem ein eindeutiges API-Token für jeden Benutzer erstellen. Folgendes 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 sich das an und lassen Sie mich wissen, wenn ich etwas verbessern kann. Vielen Dank

0
Himanshu Sharma

Ich denke, das ist die beste Methode.

str_shuffle(md5(Rand(0,100000)))
0
Davinder Kumar

wir können diese zwei Codezeilen verwenden, um eindeutige Zeichenfolgen zu generieren, die etwa 10000000 Mal iteriert wurden

  $sffledStr= str_shuffle('a[email protected]#$%^&*()_-+');
    $uniqueString = md5(time().$sffledStr);
0
IMRA

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

Ti3kE1WfGgTNxQVXtbNNbhvvapnaUfGMVJecHkUjHbuCb85pF

Hoffe, das ist, was Sie suchen ...

0
Alessandro