Domanda

Come sarebbe possibile generare una stringa casuale e univoca utilizzando numeri e lettere da utilizzare in un collegamento di verifica?Come quando crei un account su un sito web e ti invia un'e-mail con un collegamento e devi fare clic su quel collegamento per verificare il tuo account... sì... uno di quelli.

Come posso generarne uno utilizzando PHP?

Aggiornamento: Mi sono appena ricordato di uniqid().È una funzione PHP che genera un identificatore univoco basato sull'ora corrente in microsecondi.Penso che lo userò.

È stato utile?

Soluzione

  

Sicurezza Avviso : questa soluzione non deve essere utilizzato in situazioni in cui la qualità della vostra casualità può influenzare la sicurezza di un'applicazione. In particolare, rand() e uniqid() non sono crittograficamente sicuro generatori di numeri casuali . Vedi di Scott risposta per un'alternativa sicura.

Se non è necessario che sia assolutamente unico nel corso del tempo:

md5(uniqid(rand(), true))

In caso contrario (dato che avete già determinato un accesso unico per l'utente):

md5(uniqid($your_user_login, true))

Altri suggerimenti

Stavo cercando su come risolvere questo stesso problema, ma voglio anche la mia funzione di creare un token che può essere utilizzato per il recupero della password pure. Questo significa che ho bisogno di limitare la capacità del token per essere indovinato. Poiché uniqid si basa sul tempo, e secondo php.net "il valore di ritorno è poco differente da microtime () ", uniqid non soddisfa i criteri. PHP consiglia di utilizzare openssl_random_pseudo_bytes() invece per generare token crittograficamente sicuro.

Un rapido, breve e al punto di risposta è:

bin2hex(openssl_random_pseudo_bytes($bytes))

che genererà una stringa casuale di caratteri alfanumerici di lunghezza = $ bytes * 2. Purtroppo questo ha solo un alfabeto di [a-f][0-9], ma funziona.


Qui di seguito è la funzione più forte ho potuto fare che soddisfa i criteri (Questa è una versione implementata della risposta di Erik).

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) funziona come una goccia in sostituzione di rand() o mt_rand. Esso utilizza openssl_random_pseudo_bytes per contribuire a creare un numero casuale compreso tra $ min e $ max.

getToken($length) crea un alfabeto di utilizzare all'interno del token e quindi crea una stringa di lunghezza $length.

EDIT: ho trascurato di citare fonte - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322

EDIT (PHP7): Con il rilascio di PHP7, la libreria standard ha ora due nuove funzioni che possono sostituire / migliorare / semplificare la funzione crypto_rand_secure sopra. random_bytes($length) e random_int($min, $max)

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

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

Esempio:

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

Versione orientata agli oggetti della soluzione più votata

Ho creato una soluzione orientata agli oggetti basata su Scottla risposta:

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

Utilizzo

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

Alfabeto personalizzato

Se necessario, è possibile utilizzare un alfabeto personalizzato.Basta passare una stringa con caratteri supportati al costruttore o al setter:

<?php

$customAlphabet = '0123456789ABCDEF';

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

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

Ecco gli esempi di output

SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa

Spero che possa aiutare qualcuno.Saluti!

Sono in ritardo, ma io sono qui con alcuni buoni dati di ricerca sulla base delle funzioni fornite da di Scott risposta . Così ho creato una goccia dell'oceano digitale solo per questo 5-giorni di test automatizzati lungo e memorizzato le stringhe univoche generate in un database MySQL.

Durante questo periodo di prova, ho usato 5 lunghezze differenti (5, 10, 15, 20, 50) e +/- 0,5 milioni di record sono stati inseriti per ogni lunghezza. Durante la mia prova, solo la lunghezza 5 generato +/- 3K duplicati su 0,5 milioni e le restanti lunghezze non ha generato alcun duplicati. Quindi possiamo dire che se usiamo una lunghezza di 15 o superiore, con funzioni di Scott, allora possiamo generare stringhe univoche altamente affidabili. Ecco la tabella che mostra il mio dati di ricerca:

entrare descrizione dell'immagine qui

Aggiornamento: Ho creato una semplice applicazione Heroku utilizzando queste funzioni che restituisce il token come risposta JSON. L'applicazione è possibile accedere in https://uniquestrings.herokuapp.com/api/token? lunghezza = 15

Spero che questo aiuta.

Questa funzione genera una chiave casuale utilizzando numeri e lettere:

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

uscita Esempio:

zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8

È possibile utilizzare UUID (Universally Unique Identifier), può essere utilizzato per qualsiasi scopo, dalla stringa di autenticazione utente a transazione di pagamento id.

Un UUID è un numero di 16 byte (128 bit). Nella sua forma canonica, un UUID è rappresentato da 32 cifre esadecimali, mostrata in cinque gruppi separati da trattini, nella forma 8-4-4-4-12 per un totale di 36 caratteri (32 caratteri alfanumerici e quattro trattini).

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

}

// chiamando funtion

$transationID = generate_uuid();

alcune uscite esempio saranno come:

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

Spero che aiuta qualcuno in futuro :)

Io uso questo one-liner:

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

dove lunghezza è la lunghezza della stringa desiderata (divisibile per 4, altrimenti viene arrotondato al numero più vicino divisibile per 4)

  1. generare un numero casuale utilizzando il vostro preferito di numeri casuali generatore
  2. Moltiplicare e dividerlo per ottenere un numero corrispondente al numero di caratteri nel vostro alfabeto codice
  3. Scarica l'articolo a quel indice in il codice alfabeto.
  4. Ripetere dal 1) fino ad ottenere la lunghezza che vogliono

per esempio (in pseudo codice)

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

Utilizza il codice qui sotto per generare il numero casuale di 11 caratteri o cambiare il numero secondo il vostro requisito.

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

o siamo in grado di utilizzare la funzione personalizzata per generare il numero casuale

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

Ecco ultimo generatore di ID univoco per voi. fatto da me.

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

è possibile eco qualsiasi 'var' per il proprio ID come ti piace. ma $ mdun è meglio, è possibile sostituire MD5 per SHA1 per codice migliore, ma che sarà molto lunga, che potrebbe non voi bisogno.

Grazie.

Per le stringhe davvero casuali, è possibile utilizzare

<?php

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

uscite:

40a29479ec808ad4bcff288a48a25d5c

quindi, anche se si tenta di generare stringa più volte al tempo stesso esatto, otterrete output diverso.

Ecco quello che io uso:

md5(time() . rand());    
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b
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();
    }

 }

Quando si tenta di generare una password casuale che si sta tentando di:

  • In primo luogo generare un insieme crittograficamente sicuro di byte casuali

  • Secondo gira quei byte casuali in una stringa stampabile

Ora, ci sono il modo più per generare byte casuali in PHP come:

$length = 32;

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

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

Poi si vuole trasformare questi byte casuali in una stringa da stampare:

È possibile utilizzare BIN2HEX :

$string = bin2hex($bytes);

o base64_encode :

$string = base64_encode($bytes);

Tuttavia, tenere presente che non si controlla la lunghezza della stringa, se si utilizza Base64. È possibile utilizzare BIN2HEX per farlo, utilizzando 32 byte si trasformerà in un 64 stringa char . Ma funziona solo in questo modo in un EVEN della stringa.

dopo aver letto esempi precedenti sono arrivato fino a questo:

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

I duplicato 10 volte l'array [0-9, A-Z] e shuffle gli elementi, dopo ho un punto di partenza casuale per substr () per essere piu 'creativi' :) è possibile aggiungere [a-z] e altri elementi per matrice, duplicare più o meno, essere più creativi di me

Mi piace usare le chiavi hash quando si tratta link di verifica. Ti consiglio di utilizzare il microtime e hashing MD5 che l'utilizzo in quanto non vi dovrebbe essere alcun motivo per cui le chiavi dovrebbero essere gli stessi dal momento che gli hash in base al largo della microtime.

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

Questa è una semplice funzione che permette di generare stringhe casuali che contengono lettere e numeri (alfanumerici). È inoltre possibile limitare la lunghezza della stringa. Queste stringhe casuali possono essere utilizzati per vari scopi, tra cui: Referral codice, il codice promozionale, codice coupon. Funzione si basa sulla seguente funzioni PHP: 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
*/

Se si desidera generare una stringa univoca in PHP, prova a seguire.

md5(uniqid().mt_rand());

In questo,

uniqid() - Si genera stringa univoca. Questa funzione restituisce basato identificativo univoco timestamp come una stringa.

mt_rand() -. Genera numeri casuali

md5() -. Si genera la stringa hash

Scott, sì, si sta molto scrivere e buona soluzione! Grazie.

Sono anche necessari per generare token dell'API unica per la mia ogni utente. In seguito è il mio approccio, ho usato le informazioni utente (Userid e nome utente):

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

Si prega di dare un'occhiata e fatemi sapere se ogni miglioramento che posso fare. Grazie

Ecco quello che sto usando su uno dei miei progetti, sta funzionando grande e genera un UNICO RANDOM GETTONE :

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

Si prega di notare che ho moltiplicato il timestamp per tre per creare una confusione per chi utente potrebbe chiedere come si genera questo token;)

Spero che aiuta:)

Credo che questo sia il metodo migliore da utilizzare.

str_shuffle(md5(rand(0,100000)))
<?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;

}

?>

sopra funzione genera una stringa casuale che è la lunghezza di 11 caratteri.

possiamo usare questa due linee di codice per generare stringa univoca hanno testato in tutto 10 milioni tempi di iterazione

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

Io uso sempre questa la mia funzione di generare una stringa alfanumerica casuale personalizzato ... Spero che questo aiuto.

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

Esso genera ad esempio: Y1FypdjVbFCFK6Gh9FDJpe6dciwJEfV6MQGpJqAfuijaYSZ86g

Se si vuole confrontare con un'altra stringa per essere sicuro che è una sequenza unica è possibile utilizzare questo trucco ...

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

si generano due stringhe uniche:

qsBDs4JOoVRfFxyLAOGECYIsWvpcpMzAO9pypwxsqPKeAmYLOi

Ti3kE1WfGgTNxQVXtbNNbhhvvapnaUfGMVJecHkUjHbuCb85pF

Spero che questo è quello che stai cercando ...

Credo che il problema con tutte le idee esistenti è che sono probabilmente unica, ma non sicuramente univoco (come sottolineato nella risposta di Dariusz Walczak a loletech). Ho una soluzione che in realtà è unica. E 'necessario che lo script hanno una sorta di memoria. Per me questo è un database SQL. Si potrebbe anche semplicemente scrivere in un file da qualche parte. Ci sono due implementazioni:

Primo metodo: avere due campi piuttosto che 1 che forniscono unicità. Il primo campo è un numero ID non è casuale, ma è unico (il primo ID è 1, il secondo 2 ...). Se si utilizza SQL, basta definire il campo ID con la proprietà AUTO_INCREMENT. Il secondo campo non è unico ma è casuale. Questo può essere generato con una qualsiasi delle altre tecniche di persone hanno già menzionato. L'idea di Scott era buona, ma MD5 è conveniente e probabilmente abbastanza buono per la maggior parte degli scopi:

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

Secondo metodo: Sostanzialmente la stessa idea, ma inizialmente scegliere un numero massimo di stringhe che potrà mai essere generati. Questo potrebbe essere solo un numero molto grande come una trilioni di. Poi fare la stessa cosa, generare un ID, ma pad a zero in modo che tutti gli ID sono lo stesso numero di cifre. Poi basta concatenare l'ID con la stringa casuale. Sarà casuale sufficiente per la maggior parte degli scopi, ma la sezione ID farà sì che è anche unico nel suo genere.

È possibile utilizzare questo codice, Spero che sarà utile per voi.

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

Dettaglio generatore di codice a caso in PHP

Semplificare il codice Scotts sopra rimuovendo i loop non necessari che rallenta notevolmente e non lo rende più sicuro che chiamare openssl_random_pseudo_bytes solo una volta

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)
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top